[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 337, Wed Jul 24 20:58:41 2002 UTC revision 344, Sat Jul 27 23:07:33 2002 UTC
# Line 458  Line 458 
458  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
459    
460          int32_t iDirection = 0;          int32_t iDirection = 0;
461            int32_t iDirectionBackup;
462          int32_t iSAD;          int32_t iSAD;
463          VECTOR backupMV;          VECTOR backupMV;
464    
# Line 471  Line 472 
472          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
473          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
474    
475          if (iDirection)          if (iDirection) {
476                  while (!iFound) {                  while (!iFound) {
477                          iFound = 1;                          iFound = 1;
478                          backupMV = *currMV;                          backupMV = *currMV;
479                            iDirectionBackup = iDirection;
480    
481                          if (iDirection != 2)                          if (iDirectionBackup != 2)
482                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
483                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
484                          if (iDirection != 1)                          if (iDirectionBackup != 1)
485                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
486                                                                                     backupMV.y, 2);                                                                                     backupMV.y, 2);
487                          if (iDirection != 4)                          if (iDirectionBackup != 4)
488                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
489                                                                                     backupMV.y - iDiamondSize, 3);                                                                                     backupMV.y - iDiamondSize, 3);
490                          if (iDirection != 3)                          if (iDirectionBackup != 3)
491                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
492                                                                                     backupMV.y + iDiamondSize, 4);                                                                                     backupMV.y + iDiamondSize, 4);
493                    }
494          } else {          } else {
495                  currMV->x = start_x;                  currMV->x = start_x;
496                  currMV->y = start_y;                  currMV->y = start_y;
# Line 1613  Line 1616 
1616  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
1617    
1618          int32_t iDirection = 0;          int32_t iDirection = 0;
1619            int32_t iDirectionBackup;
1620          int32_t iSAD;          int32_t iSAD;
1621          VECTOR backupMV;          VECTOR backupMV;
1622    
# Line 1626  Line 1630 
1630          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1631          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1632    
1633          if (iDirection)          if (iDirection) {
1634                  while (!iFound) {                  while (!iFound) {
1635                          iFound = 1;                          iFound = 1;
1636                          backupMV = *currMV;     // since iDirection!=0, this is well defined!                          backupMV = *currMV;     // since iDirection!=0, this is well defined!
1637                            iDirectionBackup = iDirection;
1638    
1639                          if (iDirection != 2)                          if (iDirectionBackup != 2)
1640                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1641                                                                                    backupMV.y, 1);                                                                                    backupMV.y, 1);
1642                          if (iDirection != 1)                          if (iDirectionBackup != 1)
1643                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1644                                                                                    backupMV.y, 2);                                                                                    backupMV.y, 2);
1645                          if (iDirection != 4)                          if (iDirectionBackup != 4)
1646                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1647                                                                                    backupMV.y - iDiamondSize, 3);                                                                                    backupMV.y - iDiamondSize, 3);
1648                          if (iDirection != 3)                          if (iDirectionBackup != 3)
1649                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1650                                                                                    backupMV.y + iDiamondSize, 4);                                                                                    backupMV.y + iDiamondSize, 4);
1651                    }
1652          } else {          } else {
1653                  currMV->x = start_x;                  currMV->x = start_x;
1654                  currMV->y = start_y;                  currMV->y = start_y;
# Line 2868  Line 2874 
2874          int b_sad16;    /* backward (only in b-frames) search */          int b_sad16;    /* backward (only in b-frames) search */
2875          int i_sad16;    /* interpolated (both direction, b-frames only) */          int i_sad16;    /* interpolated (both direction, b-frames only) */
2876          int d_sad16;    /* direct mode (assume linear motion) */          int d_sad16;    /* direct mode (assume linear motion) */
         int dnv_sad16;  /* direct mode (assume linear motion) without correction vector */  
2877    
2878          int best_sad;          int best_sad;
2879    
2880          VECTOR f_predMV, b_predMV;      /* there is no direct prediction */          VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/
2881          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
2882    
2883          int f_count=0;          int f_count=0;
2884          int b_count=0;          int b_count=0;
2885          int i_count=0;          int i_count=0;
2886          int d_count=0;          int d_count=0;
         int dnv_count=0;  
2887          int s_count=0;          int s_count=0;
2888    
2889          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
2890      const int64_t TRD = (int32_t)time_pp;      const int64_t TRD = (int32_t)time_pp;
2891    
# Line 2896  Line 2901 
2901                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];
2902                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];
2903    
2904                          VECTOR directMV;                          mb->deltamv=zeroMV;
                         VECTOR deltaMV=zeroMV;  
2905    
2906  /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */  /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */
2907    
# Line 2913  Line 2917 
2917                          }                          }
2918  #endif  #endif
2919    
2920                          dnv_sad16 = DIRECT_PENALTY;                          d_sad16 = DIRECT_PENALTY;
2921    
2922                          if (b_mb->mode == MODE_INTER4V)                          if (b_mb->mode == MODE_INTER4V)
2923                          {                          {
# Line 2921  Line 2925 
2925                          /* same method of scaling as in decoder.c, so we copy from there */                          /* same method of scaling as in decoder.c, so we copy from there */
2926                      for (k = 0; k < 4; k++) {                      for (k = 0; k < 4; k++) {
2927    
2928                                          directMV = b_mb->mvs[k];                                          mb->directmv[k] = b_mb->mvs[k];
2929    
2930                                          mb->mvs[k].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x);                                          mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
2931                      mb->b_mvs[k].x = (int32_t) ((deltaMV.x == 0)                      mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
2932                                                                                  ? ((TRB - TRD) * directMV.x) / TRD                                                                                  ? ((TRB - TRD) * mb->directmv[k].x) / TRD
2933                                              : mb->mvs[k].x - directMV.x);                                              : mb->mvs[k].x - mb->directmv[k].x);
2934                      mb->mvs[k].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y);  
2935                          mb->b_mvs[k].y = (int32_t) ((deltaMV.y == 0)                      mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
2936                                                                                  ? ((TRB - TRD) * directMV.y) / TRD                          mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)
2937                                              : mb->mvs[k].y - directMV.y);                                                                                  ? ((TRB - TRD) * mb->directmv[k].y) / TRD
2938                                                : mb->mvs[k].y - mb->directmv[k].y);
2939    
2940                                          dnv_sad16 +=                                          d_sad16 +=
2941                                                  sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,                                                  sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,
2942                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2943                                                                  2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),                                                                  2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),
# Line 2943  Line 2948 
2948                          }                          }
2949                          else                          else
2950                          {                          {
2951                                  directMV = b_mb->mvs[0];                                  mb->directmv[3] = mb->directmv[2] = mb->directmv[1] =
2952                                    mb->directmv[0] = b_mb->mvs[0];
2953    
2954                                  mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x);                                  mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
2955                  mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0)                      mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
2956                                                                  ? ((TRB - TRD) * directMV.x) / TRD                                                                          ? ((TRB - TRD) * mb->directmv[0].x) / TRD
2957                                      : mb->mvs[0].x - directMV.x);                                      : mb->mvs[0].x - mb->directmv[0].x);
2958                  mb->mvs[0].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y);  
2959                      mb->b_mvs[0].y = (int32_t) ((deltaMV.y == 0)                      mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
2960                                                                  ? ((TRB - TRD) * directMV.y) / TRD                  mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
2961                                  : mb->mvs[0].y - directMV.y);                                                                          ? ((TRB - TRD) * mb->directmv[0].y) / TRD
2962                                        : mb->mvs[0].y - mb->directmv[0].y);
2963    
2964                                  dnv_sad16 = DIRECT_PENALTY +                                  d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
                                         sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,  
2965                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2966                                                                  i, j, 16, &mb->mvs[0], edged_width),                                                                  i, j, 16, &mb->mvs[0], edged_width),
2967                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2968                                                                  i, j, 16, &mb->b_mvs[0], edged_width),                                                                  i, j, 16, &mb->b_mvs[0], edged_width),
2969                                                    edged_width);                                                    edged_width);
2970    
   
2971              }              }
2972                        d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant);
2973    
2974                          // forward search                          // forward search
2975                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2976                                                  &frame->image, i, j,                                                  &frame->image, i, j,
2977                                                  mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */                                                  mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */
2978                                                  f_predMV.x, f_predMV.y,                         /* center is f-prediction */                                                  f_predMV.x, f_predMV.y,                         /* center is f-prediction */
2979                                                  frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)),                                                  frame->motion_flags,
2980                                                  frame->quant, frame->fcode, pParam,                                                  frame->quant, frame->fcode, pParam,
2981                                                  f_mbs, f_mbs,                                                  f_mbs, f_mbs,
2982                                                  &mb->mvs[0], &pmv_dontcare);                                                  &mb->mvs[0], &pmv_dontcare);
# Line 2981  Line 2987 
2987                                                  &frame->image, i, j,                                                  &frame->image, i, j,
2988                                                  mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */                                                  mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */
2989                                                  b_predMV.x, b_predMV.y,                         /* center is b-prediction */                                                  b_predMV.x, b_predMV.y,                         /* center is b-prediction */
2990                                                  frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)),                                                  frame->motion_flags,
2991                                                  frame->quant, frame->bcode, pParam,                                                  frame->quant, frame->bcode, pParam,
2992                                                  b_mbs, b_mbs,                                                  b_mbs, b_mbs,
2993                                                  &mb->b_mvs[0], &pmv_dontcare);                                                  &mb->b_mvs[0], &pmv_dontcare);
# Line 2995  Line 3001 
3001                                                    edged_width);                                                    edged_width);
3002                      i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,                      i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,
3003                                                                  frame->fcode, frame->quant);                                                                  frame->fcode, frame->quant);
3004                      i_sad16 += calc_delta_16(mb->b_mvs[0].y-b_predMV.y, mb->b_mvs[0].y-b_predMV.y,                      i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,
3005                                                                  frame->bcode, frame->quant);                                                                  frame->bcode, frame->quant);
3006    
3007                          // TODO: direct search                          // TODO: direct search
3008                          // predictor + delta vector in range [-32,32] (fcode=1)                          // predictor + delta vector in range [-32,32] (fcode=1)
3009    
3010  //                      i_sad16 = 65535;                          i_sad16 = 65535;
3011  //                      f_sad16 = 65535;                          f_sad16 = 65535;
3012  //                      b_sad16 = 65535;                          b_sad16 = 65535;
3013    //                      d_sad16 = 65535;
3014    
3015                          if (f_sad16 < b_sad16) {                          if (f_sad16 < b_sad16) {
3016                                  best_sad = f_sad16;                                  best_sad = f_sad16;
# Line 3018  Line 3025 
3025                                  mb->mode = MODE_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
3026                          }                          }
3027    
3028                          if (dnv_sad16 < best_sad) {                          if (d_sad16 < best_sad) {
3029    
3030                                  if (dnv_sad16 > DIRECT_UPPERLIMIT)                                  if (b_mb->mode == MODE_INTER4V)
3031                                  {                                  {
                                         /* if SAD value is too large, try same vector with MODE_INTERPOLATE  
                                            instead (interpolate has residue encoding, direct mode without MV  
                                            doesn't)  
   
                                                 This has to be replaced later by "real" direct mode, including delta  
                                                 vector and (if needed) residue encoding  
3032    
3033                                          */                                  /* same method of scaling as in decoder.c, so we copy from there */
3034                                for (k = 0; k < 4; k++) {
3035    
3036                                          directMV = b_mb->mvs[0];                                                  mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
3037                                mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
3038                                                                                            ? ((TRB - TRD) * mb->directmv[k].x) / TRD
3039                                                        : mb->mvs[k].x - mb->directmv[k].x);
3040    
3041                                mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3042                            mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)
3043                                                                                            ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3044                                                : mb->mvs[k].y - mb->directmv[k].y);
3045                                            }
3046                                    }
3047                                    else
3048                                    {
3049                                            mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
3050    
3051                                          mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x);                      mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
3052                      mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0)                                                                                  ? ((TRB - TRD) * mb->directmv[0].x) / TRD
3053                                                                                  ? ((TRB - TRD) * directMV.x) / TRD                                          : mb->mvs[0].x - mb->directmv[0].x);
                                         : mb->mvs[0].x - directMV.x);  
                         mb->mvs[0].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y);  
                         mb->b_mvs[0].y = (int32_t) ((deltaMV.y == 0)  
                                                                                 ? ((TRB - TRD) * directMV.y) / TRD  
                                             : mb->mvs[0].y - directMV.y);  
3054    
3055                                          dnv_sad16 =                              mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
                                                 sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,  
                                                   get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,  
                                                                 i, j, 16, &mb->mvs[0], edged_width),  
                                                   get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,  
                                                                 i, j, 16, &mb->b_mvs[0], edged_width),  
                                                   edged_width);  
                                 dnv_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,  
                                                                 frame->fcode, frame->quant);  
                                     dnv_sad16 += calc_delta_16(mb->b_mvs[0].y-b_predMV.y, mb->b_mvs[0].y-b_predMV.y,  
                                                                 frame->bcode, frame->quant);  
3056    
3057                                          if (dnv_sad16 < best_sad)                          mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
3058                                          {                                                                                  ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3059                                                  best_sad = dnv_sad16;                                              : mb->mvs[0].y - mb->directmv[0].y);
                                                 mb->mode = MODE_INTERPOLATE;  
3060    
3061  /*                                              fprintf(stderr,"f_sad16 = %d, b_sad16 = %d, i_sad16 = %d, dnv_sad16 = %d\n",                                          mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0];
3062                                                          f_sad16,b_sad16,i_sad16,dnv_sad16);                                          mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0];
 */                                      }  
                                 }  
                                 else  
                                 {  
                                         best_sad = dnv_sad16;  
                                         mb->mode = MODE_DIRECT_NONE_MV;  
3063                                  }                                  }
3064    
3065                                    best_sad = d_sad16;
3066                                    mb->mode = MODE_DIRECT;
3067                                    mb->mode = MODE_INTERPOLATE;            // direct mode still broken :-(
3068                          }                          }
3069    
3070                          switch (mb->mode)                          switch (mb->mode)
# Line 3087  Line 3084 
3084                                          b_predMV = mb->b_mvs[0];                                          b_predMV = mb->b_mvs[0];
3085                                          break;                                          break;
3086                                  case MODE_DIRECT:                                  case MODE_DIRECT:
3087                                          d_count++; break;                                          d_count++;
3088                                  case MODE_DIRECT_NONE_MV:                                          break;
                                         dnv_count++; break;  
3089                                  default:                                  default:
3090                                          s_count++; break;                                          s_count++;              // ???
3091                                            break;
3092                          }                          }
3093    
3094                  }                  }
3095          }          }
3096    
3097  #ifdef _DEBUG_BFRAME_STAT  #ifdef _DEBUG_BFRAME_STAT
3098          fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D0: %04d   D: %04d   S: %04d\n",          fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d   S: %04d\n",
3099                                  f_count,b_count,i_count,dnv_count,d_count,s_count);                                  f_count,b_count,i_count,d_count,s_count);
3100  #endif  #endif
3101    
3102  }  }

Legend:
Removed from v.337  
changed lines
  Added in v.344

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