[svn] / branches / release-1_3-branch / xvidcore / src / motion / estimation_bvop.c Repository:
ViewVC logotype

Diff of /branches/release-1_3-branch/xvidcore/src/motion/estimation_bvop.c

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

trunk/xvidcore/src/motion/estimation_bvop.c revision 1481, Sat Jul 10 11:23:41 2004 UTC branches/release-1_3-branch/xvidcore/src/motion/estimation_bvop.c revision 2050, Tue Oct 25 10:53:24 2011 UTC
# Line 4  Line 4 
4   *  - Motion Estimation for B-VOPs  -   *  - Motion Estimation for B-VOPs  -
5   *   *
6   *  Copyright(C) 2002 Christoph Lampert <gruel@web.de>   *  Copyright(C) 2002 Christoph Lampert <gruel@web.de>
7   *               2002 Michael Militzer <michael@xvid.org>   *               2002-2010 Michael Militzer <michael@xvid.org>
8   *               2002-2003 Radoslaw Czyz <xvid@syskin.cjb.net>   *               2002-2003 Radoslaw Czyz <xvid@syskin.cjb.net>
9   *   *
10   *  This program is free software ; you can redistribute it and/or modify   *  This program is free software ; you can redistribute it and/or modify
# 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: estimation_bvop.c,v 1.8 2004-07-10 11:23:41 syskin Exp $   * $Id$
25   *   *
26   ****************************************************************************/   ****************************************************************************/
27    
# Line 137  Line 137 
137                  xcb = xb/2; ycb = yb/2;                  xcb = xb/2; ycb = yb/2;
138          }          }
139    
140          t = d_mv_bits(xf, yf, data->predMV, data->iFcode, data->qpel^data->qpel_precision, 0)          t = d_mv_bits(xf, yf, data->predMV, data->iFcode, data->qpel^data->qpel_precision)
141                   + d_mv_bits(xb, yb, data->bpredMV, data->iFcode, data->qpel^data->qpel_precision, 0);                   + d_mv_bits(xb, yb, data->bpredMV, data->iFcode, data->qpel^data->qpel_precision);
142    
143          sad = sad16bi(data->Cur, ReferenceF, ReferenceB, data->iEdgedWidth);          sad = sad16bi(data->Cur, ReferenceF, ReferenceB, data->iEdgedWidth);
144          sad += (data->lambda16 * t * sad)>>10;          sad += (data->lambda16 * t);
145    
146          if (data->chroma && sad < *data->iMinSAD)          if (data->chroma && sad < *data->iMinSAD)
147                  sad += ChromaSAD2((xcf >> 1) + roundtab_79[xcf & 0x3],                  sad += ChromaSAD2((xcf >> 1) + roundtab_79[xcf & 0x3],
# Line 207  Line 207 
207                  if (sad > *(data->iMinSAD)) return;                  if (sad > *(data->iMinSAD)) return;
208          }          }
209    
210          sad += (data->lambda16 * d_mv_bits(x, y, zeroMV, 1, 0, 0) * sad)>>10;          sad += (data->lambda16 * d_mv_bits(x, y, zeroMV, 1, 0));
211    
212          if (data->chroma && sad < *data->iMinSAD)          if (data->chroma && sad < *data->iMinSAD)
213                  sad += ChromaSAD2((xcf >> 3) + roundtab_76[xcf & 0xf],                  sad += ChromaSAD2((xcf >> 3) + roundtab_76[xcf & 0xf],
# Line 265  Line 265 
265    
266  done:  done:
267          sad = sad16bi(data->Cur, ReferenceF, ReferenceB, data->iEdgedWidth);          sad = sad16bi(data->Cur, ReferenceF, ReferenceB, data->iEdgedWidth);
268          sad += (data->lambda16 * d_mv_bits(x, y, zeroMV, 1, 0, 0) * sad)>>10;          sad += (data->lambda16 * d_mv_bits(x, y, zeroMV, 1, 0));
269    
270          if (data->chroma && sad < *data->iMinSAD)          if (data->chroma && sad < *data->iMinSAD)
271                  sad += ChromaSAD2((xcf >> 3) + roundtab_76[xcf & 0xf],                  sad += ChromaSAD2((xcf >> 3) + roundtab_76[xcf & 0xf],
# Line 291  Line 291 
291          if ( (x > data->max_dx) || ( x < data->min_dx)          if ( (x > data->max_dx) || ( x < data->min_dx)
292                  || (y > data->max_dy) || (y < data->min_dy) ) return;                  || (y > data->max_dy) || (y < data->min_dy) ) return;
293    
         if (data->rrv && (!(x&1) && x !=0) | (!(y&1) && y !=0) ) return; /* non-zero even value */  
   
294          if (data->qpel_precision) { /* x and y are in 1/4 precision */          if (data->qpel_precision) { /* x and y are in 1/4 precision */
295                  Reference = xvid_me_interpolate16x16qpel(x, y, 0, data);                  Reference = xvid_me_interpolate16x16qpel(x, y, 0, data);
296                  current = data->currentQMV;                  current = data->currentQMV;
# Line 303  Line 301 
301                  xc = x; yc = y;                  xc = x; yc = y;
302          }          }
303          t = d_mv_bits(x, y, data->predMV, data->iFcode,          t = d_mv_bits(x, y, data->predMV, data->iFcode,
304                                          data->qpel^data->qpel_precision, data->rrv);                                          data->qpel^data->qpel_precision);
305    
306          sad = sad16(data->Cur, Reference, data->iEdgedWidth, 256*4096);          sad = sad16(data->Cur, Reference, data->iEdgedWidth, 256*4096);
307          sad += (data->lambda16 * t * sad)>>10;          sad += (data->lambda16 * t);
308    
309          if (data->chroma && sad < *data->iMinSAD)          if (data->chroma && sad < *data->iMinSAD)
310                  sad += xvid_me_ChromaSAD((xc >> 1) + roundtab_79[xc & 0x3],                  sad += xvid_me_ChromaSAD((xc >> 1) + roundtab_79[xc & 0x3],
# Line 375  Line 373 
373          Data_d->CurU = Data_f->CurU = Data_b->CurU = Data_i->CurU = Cur[1];          Data_d->CurU = Data_f->CurU = Data_b->CurU = Data_i->CurU = Cur[1];
374          Data_d->CurV = Data_f->CurV = Data_b->CurV = Data_i->CurV = Cur[2];          Data_d->CurV = Data_f->CurV = Data_b->CurV = Data_i->CurV = Cur[2];
375    
376          Data_d->lambda16 = lambda/4;          Data_d->lambda16 = Data_f->lambda16 = Data_b->lambda16 = Data_i->lambda16 = lambda;
         Data_f->lambda16 = Data_b->lambda16 = Data_i->lambda16 = lambda;  
377    
378          /* reset chroma-sad cache */          /* reset chroma-sad cache */
379          Data_d->b_chromaX = Data_d->b_chromaY = Data_d->chromaX = Data_d->chromaY = Data_d->chromaSAD = 256*4096;          Data_d->b_chromaX = Data_d->b_chromaY = Data_d->chromaX = Data_d->chromaY = Data_d->chromaSAD = 256*4096;
# Line 399  Line 396 
396                                                          const uint32_t iWcount,                                                          const uint32_t iWcount,
397                                                          const MACROBLOCK * const pMB,                                                          const MACROBLOCK * const pMB,
398                                                          const uint32_t mode_curr,                                                          const uint32_t mode_curr,
399                                                          const VECTOR hint)                                                          const VECTOR hint, const int bound)
400  {  {
401            int lx, ly;             /* left */
402            int tx, ty;             /* top */
403            int rtx, rty;   /* top-right */
404            int ltx, lty;   /* top-left */
405            int lpos, tpos, rtpos, ltpos;
406    
407            lx  = x - 1;    ly  = y;
408            tx  = x;                ty  = y - 1;
409            rtx = x + 1;    rty = y - 1;
410            ltx = x - 1;    lty = y - 1;
411    
412            lpos  =  lx +  ly * iWcount;
413            rtpos = rtx + rty * iWcount;
414            tpos  =  tx +  ty * iWcount;
415            ltpos = ltx + lty * iWcount;
416    
         /* [0] is prediction */  
         pmv[0].x = (pmv[0].x); pmv[0].y = (pmv[0].y);  
417    
418          pmv[1].x = pmv[1].y = 0; /* [1] is zero */          /* [0] is prediction */
419            /* [1] is zero */
420            pmv[1].x = pmv[1].y = 0;
421    
422          pmv[2].x = hint.x; pmv[2].y = hint.y;          pmv[2].x = hint.x; pmv[2].y = hint.y;
423    
424          if ((y != 0)&&(x != (int)(iWcount+1))) {                        /* [3] top-right neighbour */          if (rtpos >= bound && rtx < (int)iWcount) {                     /* [3] top-right neighbour */
425                  pmv[3] = ChoosePred(pMB+1-iWcount, mode_curr);                  pmv[3] = ChoosePred(pMB+1-iWcount, mode_curr);
426          } else pmv[3].x = pmv[3].y = 0;          } else pmv[3].x = pmv[3].y = 0;
427    
428          if (y != 0) {          if (tpos >= bound) {
429                  pmv[4] = ChoosePred(pMB-iWcount, mode_curr);                  pmv[4] = ChoosePred(pMB-iWcount, mode_curr);    /* [4] top */
430          } else pmv[4].x = pmv[4].y = 0;          } else pmv[4].x = pmv[4].y = 0;
431    
432          if (x != 0) {          if (lpos >= bound && lx >= 0) {
433                  pmv[5] = ChoosePred(pMB-1, mode_curr);                  pmv[5] = ChoosePred(pMB-1, mode_curr);                  /* [5] left */
434          } else pmv[5].x = pmv[5].y = 0;          } else pmv[5].x = pmv[5].y = 0;
435    
436          if (x != 0 && y != 0) {          if (ltpos >= bound && ltx >= 0) {
437                  pmv[6] = ChoosePred(pMB-1-iWcount, mode_curr);                  pmv[6] = ChoosePred(pMB-1-iWcount, mode_curr);  /* [6] top-left */
438          } else pmv[6].x = pmv[6].y = 0;          } else pmv[6].x = pmv[6].y = 0;
439  }  }
440    
# Line 437  Line 449 
449                          int32_t * const best_sad,                          int32_t * const best_sad,
450                          const int32_t mode_current,                          const int32_t mode_current,
451                          SearchData * const Data,                          SearchData * const Data,
452                          VECTOR hint)                          VECTOR hint, const int bound)
453  {  {
454    
455          int i;          int i;
# Line 448  Line 460 
460          Data->predMV = *predMV;          Data->predMV = *predMV;
461    
462          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,
463                                  pParam->width, pParam->height, iFcode - Data->qpel, 1, 0);                                  pParam->width, pParam->height, iFcode - Data->qpel, 1);
464    
465          pmv[0] = Data->predMV;          pmv[0] = Data->predMV;
466          if (Data->qpel) {          if (Data->qpel) {
# Line 456  Line 468 
468                  hint.x /= 2; hint.y /= 2;                  hint.x /= 2; hint.y /= 2;
469          }          }
470    
471          PreparePredictionsBF(pmv, x, y, pParam->mb_width, pMB, mode_current, hint);          PreparePredictionsBF(pmv, x, y, pParam->mb_width, pMB, mode_current, hint, bound);
472    
473          Data->currentMV->x = Data->currentMV->y = 0;          Data->currentMV->x = Data->currentMV->y = 0;
474    
# Line 495  Line 507 
507                  if(MotionFlags & XVID_ME_FASTREFINE16) {                  if(MotionFlags & XVID_ME_FASTREFINE16) {
508                          /* fast */                          /* fast */
509                          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,                          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,
510                                                  pParam->width, pParam->height, Data->iFcode, 2, 0);                                                  pParam->width, pParam->height, Data->iFcode, 2);
511                          FullRefine_Fast(Data, CheckCandidate16no4v, 0);                          FullRefine_Fast(Data, CheckCandidate16no4v, 0);
512    
513                  } else {                  } else {
# Line 510  Line 522 
522                                          Data->currentQMV->y = 2*Data->currentMV->y;                                          Data->currentQMV->y = 2*Data->currentMV->y;
523                                  }                                  }
524                                  get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,                                  get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,
525                                                          pParam->width, pParam->height, Data->iFcode, 2, 0);                                                          pParam->width, pParam->height, Data->iFcode, 2);
526                                  Data->qpel_precision = 1;                                  Data->qpel_precision = 1;
527                                  xvid_me_SubpelRefine(Data->currentQMV[0], Data, CheckCandidate16no4v, 0); /* qpel part */                                  xvid_me_SubpelRefine(Data->currentQMV[0], Data, CheckCandidate16no4v, 0); /* qpel part */
528                          }                          }
# Line 525  Line 537 
537  {  {
538          int k;          int k;
539    
         pMB->mode = MODE_DIRECT; /* just to initialize it */  
   
540          if (!Data->chroma) {          if (!Data->chroma) {
541                  int dx = 0, dy = 0, b_dx = 0, b_dy = 0;                  int dx = 0, dy = 0, b_dx = 0, b_dy = 0;
542                  int32_t sum;                  int32_t sum;
# Line 546  Line 556 
556                  b_dx = (b_dx >> 3) + roundtab_76[b_dx & 0xf];                  b_dx = (b_dx >> 3) + roundtab_76[b_dx & 0xf];
557    
558                  sum = sad8bi(Data->CurU,                  sum = sad8bi(Data->CurU,
559                                                  Data->RefP[4] + (dy/2) * stride + dx/2,                                                  Data->RefP[4] + (dy/2) * (int)stride + dx/2,
560                                                  Data->b_RefP[4] + (b_dy/2) * stride + b_dx/2,                                                  Data->b_RefP[4] + (b_dy/2) * (int)stride + b_dx/2,
561                                                  stride);                                                  stride);
562    
563                  if (sum >= MAX_CHROMA_SAD_FOR_SKIP * (int)Data->iQuant) return; /* no skip */                  if (sum >= MAX_CHROMA_SAD_FOR_SKIP * (int)Data->iQuant) return; /* no skip */
564    
565                  sum += sad8bi(Data->CurV,                  sum += sad8bi(Data->CurV,
566                                                  Data->RefP[5] + (dy/2) * stride + dx/2,                                                  Data->RefP[5] + (dy/2) * (int)stride + dx/2,
567                                                  Data->b_RefP[5] + (b_dy/2) * stride + b_dx/2,                                                  Data->b_RefP[5] + (b_dy/2) * (int)stride + b_dx/2,
568                                                  stride);                                                  stride);
569    
570                  if (sum >= MAX_CHROMA_SAD_FOR_SKIP * (int)Data->iQuant) return; /* no skip */                  if (sum >= MAX_CHROMA_SAD_FOR_SKIP * (int)Data->iQuant) return; /* no skip */
# Line 569  Line 579 
579          for (k = 0; k < 4; k++) {          for (k = 0; k < 4; k++) {
580                  pMB->qmvs[k] = pMB->mvs[k] = Data->directmvF[k];                  pMB->qmvs[k] = pMB->mvs[k] = Data->directmvF[k];
581                  pMB->b_qmvs[k] = pMB->b_mvs[k] =  Data->directmvB[k];                  pMB->b_qmvs[k] = pMB->b_mvs[k] =  Data->directmvB[k];
582                    if (Data->qpel) {
583                            pMB->mvs[k].x /= 2; pMB->mvs[k].y /= 2; /* it's a hint for future searches */
584                            pMB->b_mvs[k].x /= 2; pMB->b_mvs[k].y /= 2;
585                    }
586          }          }
587  }  }
588    
# Line 617  Line 631 
631    
632          CheckCandidateDirect(0, 0, Data, 255);  /* will also fill iMinSAD[1..4] with 8x8 SADs */          CheckCandidateDirect(0, 0, Data, 255);  /* will also fill iMinSAD[1..4] with 8x8 SADs */
633    
   
634          /* initial (fast) skip decision */          /* initial (fast) skip decision */
635          if (Data->iMinSAD[1] < (int)Data->iQuant * INITIAL_SKIP_THRESH          if (Data->iMinSAD[1] < (int)Data->iQuant * INITIAL_SKIP_THRESH
636                  && Data->iMinSAD[2] < (int)Data->iQuant * INITIAL_SKIP_THRESH                  && Data->iMinSAD[2] < (int)Data->iQuant * INITIAL_SKIP_THRESH
# Line 629  Line 642 
642                          return *Data->iMinSAD; /* skipped */                          return *Data->iMinSAD; /* skipped */
643          }          }
644    
645            if (Data->chroma && Data->chromaSAD >= MAX_CHROMA_SAD_FOR_SKIP * (int)Data->iQuant) /* chroma doesn't allow skip */
646                    skip_sad = 256*4096;
647            else
648          skip_sad = 4*MAX(MAX(Data->iMinSAD[1],Data->iMinSAD[2]), MAX(Data->iMinSAD[3],Data->iMinSAD[4]));          skip_sad = 4*MAX(MAX(Data->iMinSAD[1],Data->iMinSAD[2]), MAX(Data->iMinSAD[3],Data->iMinSAD[4]));
         if (Data->chroma) skip_sad += Data->chromaSAD;  
649    
650          Data->currentMV[1].x = Data->directmvF[0].x + Data->currentMV->x; /* hints for forward and backward searches */          Data->currentMV[1].x = Data->directmvF[0].x + Data->currentMV->x; /* hints for forward and backward searches */
651          Data->currentMV[1].y = Data->directmvF[0].y + Data->currentMV->y;          Data->currentMV[1].y = Data->directmvF[0].y + Data->currentMV->y;
# Line 643  Line 658 
658                          Data->directmvB[0].y                          Data->directmvB[0].y
659                          : Data->currentMV[1].y - Data->referencemv[0].y);                          : Data->currentMV[1].y - Data->referencemv[0].y);
660    
661            *best_sad = Data->iMinSAD[0];
662    
663          return skip_sad;          return skip_sad;
664  }  }
665    
# Line 711  Line 728 
728          Data->currentMV[0] = startF;          Data->currentMV[0] = startF;
729          Data->currentMV[1] = startB;          Data->currentMV[1] = startB;
730    
731          get_range(f_range, f_range+1, f_range+2, f_range+3, x, y, 4, pParam->width, pParam->height, Data->iFcode - Data->qpel, 1, 0);          get_range(f_range, f_range+1, f_range+2, f_range+3, x, y, 4, pParam->width, pParam->height, Data->iFcode - Data->qpel, 1);
732          get_range(b_range, b_range+1, b_range+2, b_range+3, x, y, 4, pParam->width, pParam->height, Data->bFcode - Data->qpel, 1, 0);          get_range(b_range, b_range+1, b_range+2, b_range+3, x, y, 4, pParam->width, pParam->height, Data->bFcode - Data->qpel, 1);
733    
734          if (Data->currentMV[0].x > f_range[1]) Data->currentMV[0].x = f_range[1];          if (Data->currentMV[0].x > f_range[1]) Data->currentMV[0].x = f_range[1];
735          if (Data->currentMV[0].x < f_range[0]) Data->currentMV[0].x = f_range[0];          if (Data->currentMV[0].x < f_range[0]) Data->currentMV[0].x = f_range[0];
# Line 741  Line 758 
758          int i, j;          int i, j;
759          int b_range[4], f_range[4];          int b_range[4], f_range[4];
760    
761          get_range(f_range, f_range+1, f_range+2, f_range+3, x, y, 4, pParam->width, pParam->height, Data->iFcode - Data->qpel, 1, 0);          get_range(f_range, f_range+1, f_range+2, f_range+3, x, y, 4, pParam->width, pParam->height, Data->iFcode - Data->qpel, 1);
762          get_range(b_range, b_range+1, b_range+2, b_range+3, x, y, 4, pParam->width, pParam->height, Data->bFcode - Data->qpel, 1, 0);          get_range(b_range, b_range+1, b_range+2, b_range+3, x, y, 4, pParam->width, pParam->height, Data->bFcode - Data->qpel, 1);
763    
764          /* diamond */          /* diamond */
765          do {          do {
# Line 772  Line 789 
789          if (Data->qpel) {          if (Data->qpel) {
790                  Data->qpel_precision = 1;                  Data->qpel_precision = 1;
791                  get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy,                  get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy,
792                          x, y, 4, pParam->width, pParam->height, Data->iFcode, 2, 0);                          x, y, 4, pParam->width, pParam->height, Data->iFcode, 2);
793    
794                  Data->currentQMV[0].x = 2 * Data->currentMV[0].x;                  Data->currentQMV[0].x = 2 * Data->currentMV[0].x;
795                  Data->currentQMV[0].y = 2 * Data->currentMV[0].y;                  Data->currentQMV[0].y = 2 * Data->currentMV[0].y;
# Line 783  Line 800 
800                          xvid_me_SubpelRefine(Data->currentQMV[0], Data, CheckCandidateInt, 1);                          xvid_me_SubpelRefine(Data->currentQMV[0], Data, CheckCandidateInt, 1);
801    
802                          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy,                          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy,
803                                  x, y, 4, pParam->width, pParam->height, Data->bFcode, 2, 0);                                  x, y, 4, pParam->width, pParam->height, Data->bFcode, 2);
804    
805                          xvid_me_SubpelRefine(Data->currentQMV[1], Data, CheckCandidateInt, 2);                          xvid_me_SubpelRefine(Data->currentQMV[1], Data, CheckCandidateInt, 2);
806                  }                  }
# Line 793  Line 810 
810  }  }
811    
812  static void  static void
813    SearchInterpolate_final_fast(const int x, const int y,
814                                                             const uint32_t MotionFlags,
815                                                             const MBParam * const pParam,
816                                                             int32_t * const best_sad,
817                                                             SearchData * const Data)
818    {
819            /* qpel refinement */
820            if (Data->qpel) {
821                    Data->qpel_precision = 1;
822                    get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy,
823                            x, y, 4, pParam->width, pParam->height, Data->iFcode, 2);
824    
825                    Data->currentQMV[0].x = 2 * Data->currentMV[0].x;
826                    Data->currentQMV[0].y = 2 * Data->currentMV[0].y;
827                    Data->currentQMV[1].x = 2 * Data->currentMV[1].x;
828                    Data->currentQMV[1].y = 2 * Data->currentMV[1].y;
829            }
830    }
831    
832    static void
833  ModeDecision_BVOP_SAD(const SearchData * const Data_d,  ModeDecision_BVOP_SAD(const SearchData * const Data_d,
834                                            const SearchData * const Data_b,                                            const SearchData * const Data_b,
835                                            const SearchData * const Data_f,                                            const SearchData * const Data_f,
# Line 800  Line 837 
837                                            MACROBLOCK * const pMB,                                            MACROBLOCK * const pMB,
838                                            const MACROBLOCK * const b_mb,                                            const MACROBLOCK * const b_mb,
839                                            VECTOR * f_predMV,                                            VECTOR * f_predMV,
840                                            VECTOR * b_predMV)                                            VECTOR * b_predMV,
841                                              int force_direct)
842  {  {
843          int mode = MODE_DIRECT, k;          int mode = MODE_DIRECT, k;
844          int best_sad, f_sad, b_sad, i_sad;          int best_sad, f_sad, b_sad, i_sad;
# Line 812  Line 850 
850          f_sad = Data_f->iMinSAD[0] + 4*Data_d->lambda16;          f_sad = Data_f->iMinSAD[0] + 4*Data_d->lambda16;
851          i_sad = Data_i->iMinSAD[0] + 2*Data_d->lambda16;          i_sad = Data_i->iMinSAD[0] + 2*Data_d->lambda16;
852    
853            if (force_direct)
854                    goto set_mode; /* bypass checks for non-direct modes */
855    
856          if (b_sad < best_sad) {          if (b_sad < best_sad) {
857                  mode = MODE_BACKWARD;                  mode = MODE_BACKWARD;
858                  best_sad = b_sad;                  best_sad = b_sad;
# Line 827  Line 868 
868                  best_sad = i_sad;                  best_sad = i_sad;
869          }          }
870    
871    set_mode:
872          pMB->sad16 = best_sad;          pMB->sad16 = best_sad;
873          pMB->mode = mode;          pMB->mode = mode;
874            pMB->cbp = 63;
875    
876          switch (mode) {          switch (mode) {
877    
# Line 875  Line 918 
918                          *f_predMV = Data_f->currentMV[0];                          *f_predMV = Data_f->currentMV[0];
919                  }                  }
920                  pMB->mvs[0] = *Data_f->currentMV;                  pMB->mvs[0] = *Data_f->currentMV;
921                    pMB->b_mvs[0] = *Data_b->currentMV; /* hint for future searches */
922                  break;                  break;
923    
924          case MODE_BACKWARD:          case MODE_BACKWARD:
# Line 889  Line 933 
933                          *b_predMV = Data_b->currentMV[0];                          *b_predMV = Data_b->currentMV[0];
934                  }                  }
935                  pMB->b_mvs[0] = *Data_b->currentMV;                  pMB->b_mvs[0] = *Data_b->currentMV;
936                    pMB->mvs[0] = *Data_f->currentMV; /* hint for future searches */
937                  break;                  break;
938    
939    
# Line 916  Line 961 
961          }          }
962  }  }
963    
964    static __inline void
965    maxMotionBVOP(int * const MVmaxF, int * const MVmaxB, const MACROBLOCK * const pMB, const int qpel)
966    {
967            if (pMB->mode == MODE_FORWARD || pMB->mode == MODE_INTERPOLATE) {
968                    const VECTOR * const mv = qpel ? pMB->qmvs : pMB->mvs;
969                    int max = *MVmaxF;
970                    if (mv[0].x > max) max = mv[0].x;
971                    else if (-mv[0].x - 1 > max) max = -mv[0].x - 1;
972                    if (mv[0].y > max) max = mv[0].y;
973                    else if (-mv[0].y - 1 > max) max = -mv[0].y - 1;
974    
975                    *MVmaxF = max;
976            }
977    
978            if (pMB->mode == MODE_BACKWARD || pMB->mode == MODE_INTERPOLATE) {
979                    const VECTOR * const mv = qpel ? pMB->b_qmvs : pMB->b_mvs;
980                    int max = *MVmaxB;
981                    if (mv[0].x > max) max = mv[0].x;
982                    else if (-mv[0].x - 1 > max) max = -mv[0].x - 1;
983                    if (mv[0].y > max) max = mv[0].y;
984                    else if (-mv[0].y - 1 > max) max = -mv[0].y - 1;
985                    *MVmaxB = max;
986            }
987    }
988    
989    
990  void  void
991  MotionEstimationBVOP(MBParam * const pParam,  MotionEstimationBVOP(MBParam * const pParam,
992                                           FRAMEINFO * const frame,                                           FRAMEINFO * const frame,
# Line 932  Line 1003 
1003                                           const IMAGE * const b_ref,                                           const IMAGE * const b_ref,
1004                                           const IMAGE * const b_refH,                                           const IMAGE * const b_refH,
1005                                           const IMAGE * const b_refV,                                           const IMAGE * const b_refV,
1006                                           const IMAGE * const b_refHV)                                           const IMAGE * const b_refHV,
1007                                             const int num_slices)
1008  {  {
1009          uint32_t i, j;          uint32_t i, j;
1010          int32_t best_sad, sad2;          int32_t best_sad = 256*4096;
1011          uint32_t skip_sad;          uint32_t skip_sad;
1012            int fb_thresh;
1013          const MACROBLOCK * const b_mbs = b_reference->mbs;          const MACROBLOCK * const b_mbs = b_reference->mbs;
1014    
1015          VECTOR f_predMV, b_predMV;          VECTOR f_predMV, b_predMV;
1016    
1017            int mb_width = pParam->mb_width;
1018            int mb_height = pParam->mb_height;
1019            int MVmaxF = 0, MVmaxB = 0;
1020          const int32_t TRB = time_pp - time_bp;          const int32_t TRB = time_pp - time_bp;
1021          const int32_t TRD = time_pp;          const int32_t TRD = time_pp;
1022            DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);
1023    
1024          /* some pre-inintialized data for the rest of the search */          /* some pre-inintialized data for the rest of the search */
1025          SearchData Data_d, Data_f, Data_b, Data_i;          SearchData Data_d, Data_f, Data_b, Data_i;
# Line 954  Line 1030 
1030          Data_d.rounding = 0;          Data_d.rounding = 0;
1031          Data_d.chroma = frame->motion_flags & XVID_ME_CHROMA_BVOP;          Data_d.chroma = frame->motion_flags & XVID_ME_CHROMA_BVOP;
1032          Data_d.iQuant = frame->quant;          Data_d.iQuant = frame->quant;
1033            Data_d.quant_sq = frame->quant*frame->quant;
1034            Data_d.dctSpace = dct_space;
1035            Data_d.quant_type = !(pParam->vol_flags & XVID_VOL_MPEGQUANT);
1036            Data_d.mpeg_quant_matrices = pParam->mpeg_quant_matrices;
1037    
1038          Data_d.RefQ = f_refV->u; /* a good place, also used in MC (for similar purpose) */          Data_d.RefQ = f_refV->u; /* a good place, also used in MC (for similar purpose) */
1039    
# Line 961  Line 1041 
1041          memcpy(&Data_b, &Data_d, sizeof(SearchData));          memcpy(&Data_b, &Data_d, sizeof(SearchData));
1042          memcpy(&Data_i, &Data_d, sizeof(SearchData));          memcpy(&Data_i, &Data_d, sizeof(SearchData));
1043    
1044          Data_f.iFcode = Data_i.iFcode = frame->fcode;          Data_f.iFcode = Data_i.iFcode = frame->fcode = b_reference->fcode;
1045          Data_b.iFcode = Data_i.bFcode = frame->bcode;          Data_b.iFcode = Data_i.bFcode = frame->bcode = b_reference->fcode;
   
1046    
1047          for (j = 0; j < pParam->mb_height; j++) {          for (j = 0; j < pParam->mb_height; j++) {
1048                    int new_bound = mb_width * ((((j*num_slices) / mb_height) * mb_height + (num_slices-1)) / num_slices);
1049    
1050                  f_predMV = b_predMV = zeroMV;   /* prediction is reset at left boundary */                  f_predMV = b_predMV = zeroMV;   /* prediction is reset at left boundary */
1051    
1052                  for (i = 0; i < pParam->mb_width; i++) {                  for (i = 0; i < pParam->mb_width; i++) {
1053                          MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width;                          MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width;
1054                          const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width;                          const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width;
1055                          int interpol_search = 0;                          int force_direct = (((j*mb_width+i)==new_bound) && (j > 0)) ? 1 : 0; /* MTK decoder chipsets do NOT reset predMVs upon resync marker in BVOPs. We workaround this problem
1056                          int bf_search = 0;                                                                                                                                                                      by placing the slice border on second MB in a row and then force the first MB to be direct mode */
1057                          int bf_thresh = 0;  
1058                          pMB->mode = -1;                          pMB->mode = -1;
1059    
1060                          initialize_searchData(&Data_d, &Data_f, &Data_b, &Data_i,                          initialize_searchData(&Data_d, &Data_f, &Data_b, &Data_i,
# Line 998  Line 1078 
1078    
1079                          if (pMB->mode == MODE_DIRECT_NONE_MV) {                          if (pMB->mode == MODE_DIRECT_NONE_MV) {
1080                                  pMB->sad16 = best_sad;                                  pMB->sad16 = best_sad;
1081                                    pMB->cbp = 0;
1082                                  continue;                                  continue;
1083                          }                          }
1084    
1085                          SearchBF_initial(i, j, frame->motion_flags, frame->fcode, pParam, pMB,                          SearchBF_initial(i, j, frame->motion_flags, frame->fcode, pParam, pMB,
1086                                                  &f_predMV, &best_sad, MODE_FORWARD, &Data_f, Data_d.currentMV[1]);                                                  &f_predMV, &best_sad, MODE_FORWARD, &Data_f, Data_d.currentMV[1], new_bound);
1087    
1088                          SearchBF_initial(i, j, frame->motion_flags, frame->bcode, pParam, pMB,                          SearchBF_initial(i, j, frame->motion_flags, frame->bcode, pParam, pMB,
1089                                                  &b_predMV, &best_sad, MODE_BACKWARD, &Data_b, Data_d.currentMV[2]);                                                  &b_predMV, &best_sad, MODE_BACKWARD, &Data_b, Data_d.currentMV[2], new_bound);
1090    
1091                          sad2 = best_sad;                          if (frame->motion_flags&XVID_ME_BFRAME_EARLYSTOP)
1092                                    fb_thresh = best_sad;
1093                            else
1094                                    fb_thresh = best_sad + (best_sad>>1);
1095    
1096                          if (Data_f.iMinSAD[0] < 2*sad2+1500)                          if (Data_f.iMinSAD[0] <= fb_thresh)
1097                                  SearchBF_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_f);                                  SearchBF_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_f);
1098    
1099                          if (Data_b.iMinSAD[0] < 2*sad2+1500)                          if (Data_b.iMinSAD[0] <= fb_thresh)
1100                                  SearchBF_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_b);                                  SearchBF_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_b);
1101    
1102                          SearchInterpolate_initial(i, j, frame->motion_flags, pParam, &f_predMV, &b_predMV, &best_sad,                          SearchInterpolate_initial(i, j, frame->motion_flags, pParam, &f_predMV, &b_predMV, &best_sad,
1103                                                                    &Data_i, Data_f.currentMV[0], Data_b.currentMV[0]);                                                                    &Data_i, Data_f.currentMV[0], Data_b.currentMV[0]);
1104    
1105                          if (((Data_i.iMinSAD[0] < 2*best_sad+2000) && (!(frame->motion_flags&XVID_ME_FAST_MODEINTERPOLATE))                          if (((Data_i.iMinSAD[0] < best_sad +(best_sad>>3)) && !(frame->motion_flags&XVID_ME_FAST_MODEINTERPOLATE))
1106                                  || Data_i.iMinSAD[0] <= best_sad))                                  || Data_i.iMinSAD[0] <= best_sad) {
1107    
1108                                  SearchInterpolate_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_i);                                  SearchInterpolate_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_i);
1109                            }
1110                            else {
1111                                    SearchInterpolate_final_fast(i, j, frame->motion_flags, pParam, &best_sad, &Data_i);
1112                            }
1113    
1114                            if (Data_d.iMinSAD[0] <= 2*best_sad)
1115                                    if ((!(frame->motion_flags&XVID_ME_SKIP_DELTASEARCH) && (best_sad > 750))
1116                                            || (best_sad > 1000))
1117    
                         if ((Data_d.iMinSAD[0] <= best_sad) && (!(frame->motion_flags&XVID_ME_SKIP_DELTASEARCH)))  
1118                                  SearchDirect_final(frame->motion_flags, b_mb, &best_sad, &Data_d);                                  SearchDirect_final(frame->motion_flags, b_mb, &best_sad, &Data_d);
1119    
   
1120                          /* final skip decision */                          /* final skip decision */
1121                          if ( (skip_sad < Data_d.iQuant * MAX_SAD00_FOR_SKIP )                          if ( (skip_sad < 2 * Data_d.iQuant * MAX_SAD00_FOR_SKIP )
1122                                  && ((100*best_sad)/(skip_sad+1) > FINAL_SKIP_THRESH) ) {                                  && ((100*best_sad)/(skip_sad+1) > FINAL_SKIP_THRESH) ) {
1123    
1124                                    Data_d.chromaSAD = 0; /* green light for chroma check */
1125    
1126                                  SkipDecisionB(pMB, &Data_d);                                  SkipDecisionB(pMB, &Data_d);
1127    
1128                                  if (pMB->mode == MODE_DIRECT_NONE_MV) { /* skipped? */                                  if (pMB->mode == MODE_DIRECT_NONE_MV) { /* skipped? */
1129                                            pMB->sad16 = skip_sad;
1130                                            pMB->cbp = 0;
1131                                            continue;
1132                                    }
1133                            }
1134    
1135                            if (frame->vop_flags & XVID_VOP_RD_BVOP)
1136                                    ModeDecision_BVOP_RD(&Data_d, &Data_b, &Data_f, &Data_i,
1137                                            pMB, b_mb, &f_predMV, &b_predMV, frame->motion_flags, frame->vop_flags, pParam, i, j, best_sad, force_direct);
1138                            else
1139                                    ModeDecision_BVOP_SAD(&Data_d, &Data_b, &Data_f, &Data_i, pMB, b_mb, &f_predMV, &b_predMV, force_direct);
1140    
1141                            maxMotionBVOP(&MVmaxF, &MVmaxB, pMB, Data_d.qpel);
1142    
1143                    }
1144            }
1145    
1146            frame->fcode = getMinFcode(MVmaxF);
1147            frame->bcode = getMinFcode(MVmaxB);
1148    }
1149    
1150    
1151    
1152    void
1153    SMPMotionEstimationBVOP(SMPData * h)
1154    {
1155            Encoder *pEnc = (Encoder *) h->pEnc;
1156    
1157            const MBParam * const pParam = &pEnc->mbParam;
1158            const FRAMEINFO * const frame = h->current;
1159            const int32_t time_bp = (int32_t)(pEnc->current->stamp - frame->stamp);
1160            const int32_t time_pp = (int32_t)(pEnc->current->stamp - pEnc->reference->stamp);
1161            /* forward (past) reference */
1162            const IMAGE * const f_ref = &pEnc->reference->image;
1163            const IMAGE * const f_refH = &pEnc->f_refh;
1164            const IMAGE * const f_refV = &pEnc->f_refv;
1165            const IMAGE * const f_refHV = &pEnc->f_refhv;
1166            /* backward (future) reference */
1167            const FRAMEINFO * const b_reference = pEnc->current;
1168            const IMAGE * const b_ref = &pEnc->current->image;
1169            const IMAGE * const b_refH = &pEnc->vInterH;
1170            const IMAGE * const b_refV = &pEnc->vInterV;
1171            const IMAGE * const b_refHV = &pEnc->vInterHV;
1172    
1173            int mb_width = pParam->mb_width;
1174            int mb_height = pParam->mb_height;
1175            int num_slices = pEnc->num_slices;
1176            int y_row = h->y_row;
1177            int y_step = h->y_step;
1178            int start_y = h->start_y;
1179            int stop_y = h->stop_y;
1180            int * complete_count_self = h->complete_count_self;
1181            const int * complete_count_above = h->complete_count_above;
1182            int max_mbs;
1183            int current_mb = 0;
1184    
1185            int32_t i, j;
1186            int32_t best_sad = 256*4096;
1187            uint32_t skip_sad;
1188            int fb_thresh;
1189            const MACROBLOCK * const b_mbs = b_reference->mbs;
1190    
1191            VECTOR f_predMV, b_predMV;
1192    
1193            int MVmaxF = 0, MVmaxB = 0;
1194            const int32_t TRB = time_pp - time_bp;
1195            const int32_t TRD = time_pp;
1196            DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);
1197    
1198            /* some pre-inintialized data for the rest of the search */
1199            SearchData Data_d, Data_f, Data_b, Data_i;
1200            memset(&Data_d, 0, sizeof(SearchData));
1201    
1202            Data_d.iEdgedWidth = pParam->edged_width;
1203            Data_d.qpel = pParam->vol_flags & XVID_VOL_QUARTERPEL ? 1 : 0;
1204            Data_d.rounding = 0;
1205            Data_d.chroma = frame->motion_flags & XVID_ME_CHROMA_BVOP;
1206            Data_d.iQuant = frame->quant;
1207            Data_d.quant_sq = frame->quant*frame->quant;
1208            Data_d.dctSpace = dct_space;
1209            Data_d.quant_type = !(pParam->vol_flags & XVID_VOL_MPEGQUANT);
1210            Data_d.mpeg_quant_matrices = pParam->mpeg_quant_matrices;
1211    
1212            Data_d.RefQ = h->RefQ;
1213    
1214            memcpy(&Data_f, &Data_d, sizeof(SearchData));
1215            memcpy(&Data_b, &Data_d, sizeof(SearchData));
1216            memcpy(&Data_i, &Data_d, sizeof(SearchData));
1217    
1218            Data_f.iFcode = Data_i.iFcode = frame->fcode;
1219            Data_b.iFcode = Data_i.bFcode = frame->bcode;
1220    
1221            max_mbs = 0;
1222    
1223            for (j = (start_y+y_row); j < stop_y; j += y_step) {
1224                    int new_bound = mb_width * ((((j*num_slices) / mb_height) * mb_height + (num_slices-1)) / num_slices);
1225    
1226                    if (j == start_y) max_mbs = pParam->mb_width; /* we can process all blocks of the first row */
1227    
1228                    f_predMV = b_predMV = zeroMV;   /* prediction is reset at left boundary */
1229    
1230                    for (i = 0; i < (int) pParam->mb_width; i++) {
1231                            MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width;
1232                            const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width;
1233                            int force_direct = (((j*mb_width+i)==new_bound) && (j > 0)) ? 1 : 0; /* MTK decoder chipsets do NOT reset predMVs upon resync marker in BVOPs. We workaround this problem
1234                                                                                                                                                                        by placing the slice border on second MB in a row and then force the first MB to be direct mode */
1235                            pMB->mode = -1;
1236    
1237                            initialize_searchData(&Data_d, &Data_f, &Data_b, &Data_i,
1238                                              i, j, f_ref, f_refH->y, f_refV->y, f_refHV->y,
1239                                              b_ref, b_refH->y, b_refV->y, b_refHV->y,
1240                                              &frame->image, b_mb);
1241    
1242                            if (current_mb >= max_mbs) {
1243                                    /* we ME-ed all macroblocks we safely could. grab next portion */
1244                                    int above_count = *complete_count_above; /* sync point */
1245                                    if (above_count == pParam->mb_width) {
1246                                            /* full line above is ready */
1247                                            above_count = pParam->mb_width+1;
1248                                            if (j < stop_y-y_step) {
1249                                                    /* this is not last line, grab a portion of MBs from the next line too */
1250                                                    above_count += MAX(0, complete_count_above[1] - 1);
1251                                            }
1252                                    }
1253    
1254                                    max_mbs = current_mb + above_count - i - 1;
1255    
1256                                    if (current_mb >= max_mbs) {
1257                                            /* current workload is zero */
1258                                            i--;
1259                                            sched_yield();
1260                                            continue;
1261                                    }
1262                            }
1263    
1264    /* special case, if collocated block is SKIPed in P-VOP: encoding is forward (0,0), cpb=0 without further ado */
1265                            if (b_reference->coding_type != S_VOP)
1266                                    if (b_mb->mode == MODE_NOT_CODED) {
1267                                            pMB->mode = MODE_NOT_CODED;
1268                                            pMB->mvs[0] = pMB->b_mvs[0] = zeroMV;
1269                                            pMB->sad16 = 0;
1270                                            *complete_count_self = i+1;
1271                                            current_mb++;
1272                                            continue;
1273                                    }
1274    
1275    /* direct search comes first, because it (1) checks for SKIP-mode
1276            and (2) sets very good predictions for forward and backward search */
1277                            skip_sad = SearchDirect_initial(i, j, frame->motion_flags, TRB, TRD, pParam, pMB,
1278                                                                                            b_mb, &best_sad, &Data_d);
1279    
1280                            if (pMB->mode == MODE_DIRECT_NONE_MV) {
1281                                          pMB->sad16 = best_sad;                                          pMB->sad16 = best_sad;
1282                                    pMB->cbp = 0;
1283                                    *complete_count_self = i+1;
1284                                    current_mb++;
1285                                    continue;
1286                            }
1287    
1288                            SearchBF_initial(i, j, frame->motion_flags, frame->fcode, pParam, pMB,
1289                                                    &f_predMV, &best_sad, MODE_FORWARD, &Data_f, Data_d.currentMV[1], new_bound);
1290    
1291                            SearchBF_initial(i, j, frame->motion_flags, frame->bcode, pParam, pMB,
1292                                                    &b_predMV, &best_sad, MODE_BACKWARD, &Data_b, Data_d.currentMV[2], new_bound);
1293    
1294                            if (frame->motion_flags&XVID_ME_BFRAME_EARLYSTOP)
1295                                    fb_thresh = best_sad;
1296                            else
1297                                    fb_thresh = best_sad + (best_sad>>1);
1298    
1299                            if (Data_f.iMinSAD[0] <= fb_thresh)
1300                                    SearchBF_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_f);
1301    
1302                            if (Data_b.iMinSAD[0] <= fb_thresh)
1303                                    SearchBF_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_b);
1304    
1305                            SearchInterpolate_initial(i, j, frame->motion_flags, pParam, &f_predMV, &b_predMV, &best_sad,
1306                                                                      &Data_i, Data_f.currentMV[0], Data_b.currentMV[0]);
1307    
1308                            if (((Data_i.iMinSAD[0] < best_sad +(best_sad>>3)) && !(frame->motion_flags&XVID_ME_FAST_MODEINTERPOLATE))
1309                                    || Data_i.iMinSAD[0] <= best_sad)
1310    
1311                                    SearchInterpolate_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_i);
1312    
1313                            if (Data_d.iMinSAD[0] <= 2*best_sad)
1314                                    if ((!(frame->motion_flags&XVID_ME_SKIP_DELTASEARCH) && (best_sad > 750))
1315                                            || (best_sad > 1000))
1316    
1317                                            SearchDirect_final(frame->motion_flags, b_mb, &best_sad, &Data_d);
1318    
1319                            /* final skip decision */
1320                            if ( (skip_sad < 2 * Data_d.iQuant * MAX_SAD00_FOR_SKIP )
1321                                    && ((100*best_sad)/(skip_sad+1) > FINAL_SKIP_THRESH) ) {
1322    
1323                                    Data_d.chromaSAD = 0; /* green light for chroma check */
1324    
1325                                    SkipDecisionB(pMB, &Data_d);
1326    
1327                                    if (pMB->mode == MODE_DIRECT_NONE_MV) { /* skipped? */
1328                                            pMB->sad16 = skip_sad;
1329                                            pMB->cbp = 0;
1330                                            *complete_count_self = i+1;
1331                                            current_mb++;
1332                                          continue;                                          continue;
1333                                  }                                  }
1334                          }                          }
1335    
1336                          ModeDecision_BVOP_SAD(&Data_d, &Data_b, &Data_f, &Data_i, pMB, b_mb, &f_predMV, &b_predMV);                          if (frame->vop_flags & XVID_VOP_RD_BVOP)
1337                                    ModeDecision_BVOP_RD(&Data_d, &Data_b, &Data_f, &Data_i,
1338                                            pMB, b_mb, &f_predMV, &b_predMV, frame->motion_flags, frame->vop_flags, pParam, i, j, best_sad, force_direct);
1339                            else
1340                                    ModeDecision_BVOP_SAD(&Data_d, &Data_b, &Data_f, &Data_i, pMB, b_mb, &f_predMV, &b_predMV, force_direct);
1341    
1342                            *complete_count_self = i+1;
1343                            current_mb++;
1344                            maxMotionBVOP(&MVmaxF, &MVmaxB, pMB, Data_d.qpel);
1345                  }                  }
1346    
1347                    complete_count_self++;
1348                    complete_count_above++;
1349          }          }
1350    
1351            h->minfcode = getMinFcode(MVmaxF);
1352            h->minbcode = getMinFcode(MVmaxB);
1353  }  }

Legend:
Removed from v.1481  
changed lines
  Added in v.2050

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