--- motion_est.c 2002/07/21 23:34:08 1.35 +++ motion_est.c 2002/07/27 23:47:01 1.39 @@ -458,6 +458,7 @@ /* Do a diamond search around given starting point, return SAD of best */ int32_t iDirection = 0; + int32_t iDirectionBackup; int32_t iSAD; VECTOR backupMV; @@ -471,23 +472,25 @@ CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); - if (iDirection) + if (iDirection) { while (!iFound) { iFound = 1; backupMV = *currMV; + iDirectionBackup = iDirection; - if (iDirection != 2) + if (iDirectionBackup != 2) CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); - if (iDirection != 1) + if (iDirectionBackup != 1) CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); - if (iDirection != 4) + if (iDirectionBackup != 4) CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); - if (iDirection != 3) + if (iDirectionBackup != 3) CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); + } } else { currMV->x = start_x; currMV->y = start_y; @@ -551,7 +554,7 @@ backupMV.y + iDiamondSize, 8); - if (iDirection) + if (iDirection) { while (!iFound) { iFound = 1; backupMV = *currMV; @@ -560,62 +563,62 @@ case 1: CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); break; case 2: - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; case 3: - CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; case 4: - CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); break; case 5: - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); - CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); break; case 6: - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); - CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; @@ -623,48 +626,49 @@ case 7: CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); - CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; case 8: - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); - CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; default: - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); - CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); - CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); - CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); - CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, + CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; } + } } else { currMV->x = start_x; currMV->y = start_y; @@ -1613,6 +1617,7 @@ /* Do a diamond search around given starting point, return SAD of best */ int32_t iDirection = 0; + int32_t iDirectionBackup; int32_t iSAD; VECTOR backupMV; @@ -1626,23 +1631,206 @@ CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); - if (iDirection) + if (iDirection) { while (!iFound) { iFound = 1; backupMV = *currMV; // since iDirection!=0, this is well defined! + iDirectionBackup = iDirection; - if (iDirection != 2) + if (iDirectionBackup != 2) CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); - if (iDirection != 1) + if (iDirectionBackup != 1) CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); - if (iDirection != 4) + if (iDirectionBackup != 4) CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); - if (iDirection != 3) + if (iDirectionBackup != 3) CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); + } + } else { + currMV->x = start_x; + currMV->y = start_y; + } + return iMinSAD; +} + + + + +int32_t +Square8_MainSearch(const uint8_t * const pRef, + const uint8_t * const pRefH, + const uint8_t * const pRefV, + const uint8_t * const pRefHV, + const uint8_t * const cur, + const int x, + const int y, + int32_t start_x, + int32_t start_y, + int32_t iMinSAD, + VECTOR * const currMV, + const int center_x, + const int center_y, + const int32_t min_dx, + const int32_t max_dx, + const int32_t min_dy, + const int32_t max_dy, + const int32_t iEdgedWidth, + const int32_t iDiamondSize, + const int32_t iFcode, + const int32_t iQuant, + int iFound) +{ +/* Do a square search around given starting point, return SAD of best */ + + int32_t iDirection = 0; + int32_t iSAD; + VECTOR backupMV; + + backupMV.x = start_x; + backupMV.y = start_y; + +/* It's one search with full square pattern, and new parts for all following diamonds */ + +/* new direction are extra, so 1-4 is normal diamond + 537 + 1*2 + 648 +*/ + + CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1); + CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2); + CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); + CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); + + CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, + backupMV.y - iDiamondSize, 5); + CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, + backupMV.y + iDiamondSize, 6); + CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, + backupMV.y - iDiamondSize, 7); + CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, + backupMV.y + iDiamondSize, 8); + + + if (iDirection) { + while (!iFound) { + iFound = 1; + backupMV = *currMV; + + switch (iDirection) { + case 1: + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y, 1); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y - iDiamondSize, 5); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y - iDiamondSize, 7); + break; + case 2: + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, + 2); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y + iDiamondSize, 6); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y + iDiamondSize, 8); + break; + + case 3: + CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, + 4); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y - iDiamondSize, 7); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y + iDiamondSize, 8); + break; + + case 4: + CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, + 3); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y - iDiamondSize, 5); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y + iDiamondSize, 6); + break; + + case 5: + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, + 1); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, + 3); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y - iDiamondSize, 5); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y + iDiamondSize, 6); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y - iDiamondSize, 7); + break; + + case 6: + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, + 2); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, + 3); + + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y - iDiamondSize, 5); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y + iDiamondSize, 6); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y + iDiamondSize, 8); + + break; + + case 7: + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y, 1); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, + 4); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y - iDiamondSize, 5); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y - iDiamondSize, 7); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y + iDiamondSize, 8); + break; + + case 8: + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, + 2); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, + 4); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y + iDiamondSize, 6); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y - iDiamondSize, 7); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y + iDiamondSize, 8); + break; + default: + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, + 1); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, + 2); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, + 3); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, + 4); + + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y - iDiamondSize, 5); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, + backupMV.y + iDiamondSize, 6); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y - iDiamondSize, 7); + CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, + backupMV.y + iDiamondSize, 8); + break; + } + } } else { currMV->x = start_x; currMV->y = start_y; @@ -1650,6 +1838,10 @@ return iMinSAD; } + + + + int32_t Halfpel8_Refine_c(const uint8_t * const pRef, const uint8_t * const pRefH, @@ -1788,9 +1980,9 @@ // Prepare for main loop -// if (MotionFlags & PMV_USESQUARES8) -// MainSearchPtr = Square8_MainSearch; -// else + if (MotionFlags & PMV_USESQUARES8) + MainSearchPtr = Square8_MainSearch; + else if (MotionFlags & PMV_ADVANCEDDIAMOND8) MainSearchPtr = AdvDiamond8_MainSearch; @@ -2468,9 +2660,9 @@ // there is no EPZS^2 for inter4v at the moment -// if (MotionFlags & PMV_USESQUARES8) -// MainSearchPtr = Square8_MainSearch; -// else + if (MotionFlags & PMV_USESQUARES8) + MainSearchPtr = Square8_MainSearch; + else if (MotionFlags & PMV_ADVANCEDDIAMOND8) MainSearchPtr = AdvDiamond8_MainSearch; @@ -2868,19 +3060,18 @@ int b_sad16; /* backward (only in b-frames) search */ int i_sad16; /* interpolated (both direction, b-frames only) */ int d_sad16; /* direct mode (assume linear motion) */ - int dnv_sad16; /* direct mode (assume linear motion) without correction vector */ int best_sad; - VECTOR f_predMV, b_predMV; /* there is no direct prediction */ + VECTOR f_predMV, b_predMV; /* there is no prediction for direct mode*/ VECTOR pmv_dontcare; int f_count=0; int b_count=0; int i_count=0; int d_count=0; - int dnv_count=0; int s_count=0; + const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp; const int64_t TRD = (int32_t)time_pp; @@ -2896,11 +3087,11 @@ const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width]; const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width]; - VECTOR directMV; - VECTOR deltaMV=zeroMV; + mb->deltamv=zeroMV; /* special case, if collocated block is SKIPed: encoding is forward(0,0) */ +#ifndef _DISABLE_SKIP if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 && b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) { mb->mode = MODE_NOT_CODED; @@ -2910,8 +3101,9 @@ mb->b_mvs[0].y = 0; continue; } +#endif - dnv_sad16 = DIRECT_PENALTY; + d_sad16 = DIRECT_PENALTY; if (b_mb->mode == MODE_INTER4V) { @@ -2919,18 +3111,19 @@ /* same method of scaling as in decoder.c, so we copy from there */ for (k = 0; k < 4; k++) { - directMV = b_mb->mvs[k]; + mb->directmv[k] = b_mb->mvs[k]; - mb->mvs[k].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x); - mb->b_mvs[k].x = (int32_t) ((deltaMV.x == 0) - ? ((TRB - TRD) * directMV.x) / TRD - : mb->mvs[k].x - directMV.x); - mb->mvs[k].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y); - mb->b_mvs[k].y = (int32_t) ((deltaMV.y == 0) - ? ((TRB - TRD) * directMV.y) / TRD - : mb->mvs[k].y - directMV.y); + mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x); + mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0) + ? ((TRB - TRD) * mb->directmv[k].x) / TRD + : mb->mvs[k].x - mb->directmv[k].x); + + mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); + mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0) + ? ((TRB - TRD) * mb->directmv[k].y) / TRD + : mb->mvs[k].y - mb->directmv[k].y); - dnv_sad16 += + d_sad16 += sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width, get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, 2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width), @@ -2941,34 +3134,35 @@ } else { - directMV = b_mb->mvs[0]; + mb->directmv[3] = mb->directmv[2] = mb->directmv[1] = + mb->directmv[0] = b_mb->mvs[0]; - mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x); - mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0) - ? ((TRB - TRD) * directMV.x) / TRD - : 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); + mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x); + mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0) + ? ((TRB - TRD) * mb->directmv[0].x) / TRD + : mb->mvs[0].x - mb->directmv[0].x); + + mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y); + mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0) + ? ((TRB - TRD) * mb->directmv[0].y) / TRD + : mb->mvs[0].y - mb->directmv[0].y); - dnv_sad16 = DIRECT_PENALTY + - sad16bi(frame->image.y + i * 16 + j * 16 * edged_width, + d_sad16 += 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); - } + d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant); // forward search f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, &frame->image, i, j, mb->mvs[0].x, mb->mvs[0].y, /* start point f_directMV */ f_predMV.x, f_predMV.y, /* center is f-prediction */ - frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)), + frame->motion_flags, frame->quant, frame->fcode, pParam, f_mbs, f_mbs, &mb->mvs[0], &pmv_dontcare); @@ -2979,7 +3173,7 @@ &frame->image, i, j, mb->b_mvs[0].x, mb->b_mvs[0].y, /* start point b_directMV */ b_predMV.x, b_predMV.y, /* center is b-prediction */ - frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)), + frame->motion_flags, frame->quant, frame->bcode, pParam, b_mbs, b_mbs, &mb->b_mvs[0], &pmv_dontcare); @@ -2993,15 +3187,16 @@ edged_width); i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y, frame->fcode, frame->quant); - 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, frame->bcode, frame->quant); // TODO: direct search // predictor + delta vector in range [-32,32] (fcode=1) -// i_sad16 = 65535; -// f_sad16 = 65535; -// b_sad16 = 65535; + i_sad16 = 65535; + f_sad16 = 65535; + b_sad16 = 65535; +// d_sad16 = 65535; if (f_sad16 < b_sad16) { best_sad = f_sad16; @@ -3016,56 +3211,46 @@ mb->mode = MODE_INTERPOLATE; } - if (dnv_sad16 < best_sad) { + if (d_sad16 < best_sad) { - if (dnv_sad16 > DIRECT_UPPERLIMIT) - { - /* 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 - - */ - - directMV = b_mb->mvs[0]; - - mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x); - mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0) - ? ((TRB - TRD) * directMV.x) / TRD - : 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); + if (b_mb->mode == MODE_INTER4V) + { - dnv_sad16 = - 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); + /* same method of scaling as in decoder.c, so we copy from there */ + for (k = 0; k < 4; k++) { - if (dnv_sad16 < best_sad) - { - best_sad = dnv_sad16; - mb->mode = MODE_INTERPOLATE; - -/* fprintf(stderr,"f_sad16 = %d, b_sad16 = %d, i_sad16 = %d, dnv_sad16 = %d\n", - f_sad16,b_sad16,i_sad16,dnv_sad16); -*/ } + mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x); + mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0) + ? ((TRB - TRD) * mb->directmv[k].x) / TRD + : mb->mvs[k].x - mb->directmv[k].x); + + mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); + mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0) + ? ((TRB - TRD) * mb->directmv[k].y) / TRD + : mb->mvs[k].y - mb->directmv[k].y); + } } else { - best_sad = dnv_sad16; - mb->mode = MODE_DIRECT_NONE_MV; - } + mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x); + + mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0) + ? ((TRB - TRD) * mb->directmv[0].x) / TRD + : mb->mvs[0].x - mb->directmv[0].x); + + mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y); + + mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0) + ? ((TRB - TRD) * mb->directmv[0].y) / TRD + : mb->mvs[0].y - mb->directmv[0].y); + + mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0]; + mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0]; + } + + best_sad = d_sad16; + mb->mode = MODE_DIRECT; + mb->mode = MODE_INTERPOLATE; // direct mode still broken :-( } switch (mb->mode) @@ -3085,19 +3270,19 @@ b_predMV = mb->b_mvs[0]; break; case MODE_DIRECT: - d_count++; break; - case MODE_DIRECT_NONE_MV: - dnv_count++; break; + d_count++; + break; default: - s_count++; break; + s_count++; // ??? + break; } } } #ifdef _DEBUG_BFRAME_STAT - fprintf(stderr,"B-Stat: F: %04d B: %04d I: %04d D0: %04d D: %04d S: %04d\n", - f_count,b_count,i_count,dnv_count,d_count,s_count); + fprintf(stderr,"B-Stat: F: %04d B: %04d I: %04d D: %04d S: %04d\n", + f_count,b_count,i_count,d_count,s_count); #endif }