📄 motion_est.c
字号:
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 diamond search around given starting point, return SAD of best */ int32_t iDirection = 0; int32_t iDirectionBackup; int32_t iSAD; VECTOR backupMV; backupMV.x = start_x; backupMV.y = start_y;/* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */ CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1); CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2); CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); if (iDirection) { while (!iFound) { iFound = 1; backupMV = *currMV; iDirectionBackup = iDirection; if (iDirectionBackup != 2) CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); if (iDirectionBackup != 1) CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); if (iDirectionBackup != 4) CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); if (iDirectionBackup != 3) CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); } } else { currMV->x = start_x; currMV->y = start_y; } return iMinSAD;}int32_tSquare16_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, const int start_x, const int start_y, int 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_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1); CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2); CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); if (iDirection) { while (!iFound) { iFound = 1; backupMV = *currMV; switch (iDirection) { case 1: CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); break; case 2: CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; case 3: CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; case 4: CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); break; case 5: CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); break; case 6: CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; case 7: CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; case 8: CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; default: CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, 1); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, 2); CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, 3); CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, 4); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y - iDiamondSize, 5); CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y + iDiamondSize, 6); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y - iDiamondSize, 7); CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y + iDiamondSize, 8); break; } } } else { currMV->x = start_x; currMV->y = start_y; } return iMinSAD;}int32_tFull16_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, const int start_x, const int start_y, int 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){ int32_t iSAD; int32_t dx, dy; VECTOR backupMV; backupMV.x = start_x; backupMV.y = start_y; for (dx = min_dx; dx <= max_dx; dx += iDiamondSize) for (dy = min_dy; dy <= max_dy; dy += iDiamondSize) NOCHECK_MV16_CANDIDATE(dx, dy); return iMinSAD;}int32_tAdvDiamond16_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, const int start_xi, const int start_yi, int 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 iDirection){ int32_t iSAD; int start_x = start_xi, start_y = start_yi;/* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */ if (iDirection) { CHECK_MV16_CANDIDATE(start_x - iDiamondSize, start_y); CHECK_MV16_CANDIDATE(start_x + iDiamondSize, start_y); CHECK_MV16_CANDIDATE(start_x, start_y - iDiamondSize); CHECK_MV16_CANDIDATE(start_x, start_y + iDiamondSize); } else { int bDirection = 1 + 2 + 4 + 8; do { iDirection = 0; if (bDirection & 1) /*we only want to check left if we came from the right (our last motion was to the left, up-left or down-left) */ CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1); if (bDirection & 2) CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2); if (bDirection & 4) CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4); if (bDirection & 8) CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8); /* now we're doing diagonal checks near our candidate */ if (iDirection) /*checking if anything found */ { bDirection = iDirection; iDirection = 0; start_x = currMV->x; start_y = currMV->y; if (bDirection & 3) /*our candidate is left or right */ { CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8); CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4); } else /* what remains here is up or down */ { CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2); CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1); } if (iDirection) { bDirection += iDirection; start_x = currMV->x; start_y = currMV->y; } } else /*about to quit, eh? not so fast.... */ { switch (bDirection) { case 2: CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y - iDiamondSize, 2 + 4); CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y + iDiamondSize, 2 + 8); break; case 1: CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y - iDiamondSize, 1 + 4); CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y + iDiamondSize, 1 + 8); break; case 2 + 4: CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y - iDiamondSize, 1 + 4); CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y - iDiamondSize, 2 + 4); CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y + iDiamondSize, 2 + 8); break; case 4: CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y - iDiamondSize, 2 + 4); CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y - iDiamondSize, 1 + 4); break; case 8: CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y + iDiamondSize, 2 + 8); CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y + iDiamondSize, 1 + 8); break; case 1 + 4: CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y + iDiamondSize, 1 + 8); CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y - iDiamondSize, 1 + 4); CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y - iDiamondSize, 2 + 4); break; case 2 + 8: CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y - iDiamondSize, 1 + 4); CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y + iDiamondSize, 1 + 8); CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y + iDiamondSize, 2 + 8); break; case 1 + 8: CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y - iDiamondSize, 2 + 4); CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y + iDiamondSize, 2 + 8); CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y + iDiamondSize, 1 + 8); break; default: /*1+2+4+8 == we didn't find anything at all */ CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y - iDiamondSize, 1 + 4); CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y + iDiamondSize, 1 + 8); CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y - iDiamondSize, 2 + 4); CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y + iDiamondSize, 2 + 8); break; } if (!iDirection) break; /*ok, the end. really */ else { bDirection = iDirection; start_x = currMV->x; start_y = currMV->y; } } } while (1); /*forever */ } return iMinSAD;}int32_tAdvDiamond8_MainSearch(const uint8_t * const pRef,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -