📄 meutility.c
字号:
void matchBlockLong(mbPart_s *mbPart, int startX, int stopX, int startY, int stopY, int step, motVec_s *bestVec, int *bestSad, int low_complex_prof3){ motVec_s lclBestVec; int j, vecX, vecY; int currSad; int lclBestSad; int overhead; int refW, blkH; int lambda; int partialSum = 0; int *origPsPtr; u_int16 *refPsPtr; u_int8 *refLine, *refPtr, *orig; u_int16 *refPsLine; const int8 *vlcMvBitsX; // *retSad should have the SAD of the best estimate already // could be INT_MAX if such an estimate is not available lclBestSad = *bestSad; lclBestVec = *bestVec; blkH = mbPart->height; orig = mbPart->orig; refW = mbPart->refWidth; lambda = mbPart->lambdaCoarse; vlcMvBitsX = mbPart->vlcMvBitsX; switch (mbPart->width) { case 4: /* Scan motion vectors within search area */ for (vecY = startY; vecY <= stopY; vecY += step) { refLine = & mbPart->ref[(vecY >> 1) * refW]; overhead = (int) mbPart->vlcMvBitsY[vecY] * lambda; for (vecX = startX; vecX <= stopX; vecX += step) { /* Take into account number fo bits spent for motion vector */ currSad = lambda * vlcMvBitsX[vecX] + overhead; /* Accumulate sad until no pels left or sad is worse than best so far */ if (currSad < lclBestSad) { refPtr = refLine + (vecX >> 1); findSAD2_4x(orig, refPtr, refW, blkH, currSad, lclBestSad, j); if (currSad < lclBestSad) { lclBestSad = currSad; lclBestVec.x = (int16)vecX; lclBestVec.y = (int16)vecY; } } } } break; case 8: /* Scan motion vectors within search area */ for (vecY = startY; vecY <= stopY; vecY += step) { refPsLine = & mbPart->refPartSum[(vecY >> 2) * (refW >> 1)]; refLine = & mbPart->ref[(vecY >> 1) * refW]; overhead = (int) mbPart->vlcMvBitsY[vecY] * lambda; for (vecX = startX; vecX <= stopX; vecX += step) { /* Take into account number fo bits spent for motion vector */ currSad = lambda * vlcMvBitsX[vecX] + overhead; // calculate the partial results here // : take away partial sum if (!low_complex_prof3) { refPsPtr = refPsLine + (vecX >> 2); origPsPtr = mbPart->partSum; partialSum = 0; if (blkH >= 8) partialSum = abs(refPsPtr[0] - origPsPtr[0]); if (blkH == 16) partialSum += abs(refPsPtr[4 * refW] - origPsPtr[8]); } /* Accumulate sad until no pels left or sad is worse than best so far */ // : take away partial sum if ( ( (!low_complex_prof3) && (partialSum + currSad < lclBestSad) ) || (low_complex_prof3) ) { refPtr = refLine + (vecX >> 1); currSad = findSad2_8x(orig, refPtr, refW, blkH, currSad, lclBestSad); if (currSad < lclBestSad) { lclBestSad = currSad; lclBestVec.x = (int16)vecX; lclBestVec.y = (int16)vecY; } } } } break; default: // blk->width == 16 /* Scan motion vectors within search area */ for (vecY = startY; vecY <= stopY; vecY += step) { refPsLine = & mbPart->refPartSum[(vecY >> 2) * (refW >> 1)]; refLine = & mbPart->ref[(vecY >> 1) * refW]; overhead = (int) mbPart->vlcMvBitsY[vecY] * lambda; for (vecX = startX; vecX <= stopX; vecX += step) { /* Take into account number fo bits spent for motion vector */ currSad = lambda * vlcMvBitsX[vecX] + overhead; if (mbPart->mode == MOT_16x16) { if ((vecY | vecX) == 0) currSad -= lambda * ZERO_VEC_SAD; } // calculate the partial results here // : take away partial sum if (!low_complex_prof3) { refPsPtr = refPsLine + (vecX >> 2); origPsPtr = mbPart->partSum; partialSum = abs(refPsPtr[0] - origPsPtr[0]); partialSum += abs(refPsPtr[8] - origPsPtr[2]); if (blkH == 16) { partialSum += abs(refPsPtr[4 * refW + 0] - origPsPtr[8]); partialSum += abs(refPsPtr[4 * refW + 8] - origPsPtr[10]); } } // : take away partial sum /* Accumulate sad until no pels left or sad is worse than best so far */ if ( ( (!low_complex_prof3) && (partialSum + currSad < lclBestSad) ) || (low_complex_prof3) ) { refPtr = refLine + (vecX >> 1); currSad = findSad2_16x(orig, refPtr, refW, blkH, currSad, lclBestSad); if (currSad < lclBestSad) { lclBestSad = currSad; lclBestVec.x = (int16)vecX; lclBestVec.y = (int16)vecY; } } } } break; } *bestSad = lclBestSad; *bestVec = lclBestVec;}// center has been searched alreadymotVec_s searchPatt[9] ={ {-1, 0}, { 0, -1}, { 1, 0}, { 0, 1}, {-1, -1}, { 1, -1}, {-1, 1}, { 1, 1}, {0, 0}};int matchBlockLocal4(mbPart_s *mbPart, int step, motVec_s *bestVec, int *bestSad, int *neighborSads){ motVec_s centerVec, lclBestVec; int i, vecX, vecY; int currSad; int lclBestSad; int lambda; int centerBest; motVec_s lclSearchPatt[8]; lambda = mbPart->lambdaCoarse; centerVec = *bestVec; lclBestVec = *bestVec; lclBestSad = *bestSad; for (i = 0; i < 4; i ++) { lclSearchPatt[i].x = (int16) (searchPatt[i].x * step); lclSearchPatt[i].y = (int16) (searchPatt[i].y * step); } /* Scan motion vectors within search area */ centerBest = 1; for (i = 0; i < 4; i ++) { vecX = centerVec.x + lclSearchPatt[i].x; vecY = centerVec.y + lclSearchPatt[i].y; /* Take into account number fo bits spent for motion vector */ currSad = lambda * (mbPart->vlcMvBitsX[vecX] + mbPart->vlcMvBitsY[vecY]); /* Favor 16x16 blocks that have zero motion */ if (mbPart->mode == MOT_16x16) { if ((vecY | vecX) == 0) currSad -= lambda * ZERO_VEC_SAD; } /* Accumulate sad until no pels left or sad is worse than best so far */ currSad = findSAD2(mbPart->orig, mbPart->ref, mbPart->refWidth, mbPart->width, mbPart->height, vecX, vecY, currSad, INT_MAX); neighborSads[i] = currSad; if (currSad < lclBestSad) { centerBest = 0; lclBestSad = currSad; lclBestVec.x = (int16)vecX; lclBestVec.y = (int16)vecY; } } *bestVec = lclBestVec; *bestSad = lclBestSad; return centerBest;}void matchBlockDiamond(mbPart_s *mbPart, int step, motVec_s *bestVec, int *bestSad, int hadamard){ motVec_s centerVec, lclBestVec, lastBestVec; int i, vecX, vecY; int currSad; int lclBestSad; int lambda; int numPositions; motVec_s lclSearchPatt[9]; lambda = mbPart->lambdaCoarse; centerVec = *bestVec; lclBestVec = *bestVec; lclBestSad = *bestSad; lastBestVec = lclBestVec; if (mbPart->profile == PROF_CODING_SPEED) numPositions = 6; else numPositions = 9; for (i = 0; i < numPositions; i ++) { lclSearchPatt[i].x = (int16) (searchPatt[i].x * step); lclSearchPatt[i].y = (int16) (searchPatt[i].y * step); } /* Scan motion vectors within search area */ for (i = 0; i < numPositions; i ++) { vecX = centerVec.x + lclSearchPatt[i].x; vecY = centerVec.y + lclSearchPatt[i].y; /* Take into account number fo bits spent for motion vector */ currSad = lambda * (mbPart->vlcMvBitsX[vecX] + mbPart->vlcMvBitsY[vecY]); /* Favor 16x16 blocks that have zero motion */ if (mbPart->mode == MOT_16x16) { if ((vecY | vecX) == 0) currSad -= lambda * ZERO_VEC_SAD; } /* Accumulate sad until no pels left or sad is worse than best so far */ if (currSad < lclBestSad) { if (step == 1) { currSad = findSATD4(mbPart->orig, mbPart->ref, mbPart->refWidth, mbPart->width, mbPart->height, vecX, vecY, currSad, lclBestSad, hadamard); } else { currSad = findSAD2(mbPart->orig, mbPart->ref, mbPart->refWidth, mbPart->width, mbPart->height, vecX, vecY, currSad, lclBestSad); } if (currSad < lclBestSad) { lclBestSad = currSad; lclBestVec.x = (int16)vecX; lclBestVec.y = (int16)vecY; } } // let's see if the center is changed if (mbPart->profile == PROF_CODING_SPEED) { if (i == 3) { if ((lastBestVec.x == lclBestVec.x) && (lastBestVec.y == lclBestVec.y)) break; else { if (lastBestVec.x == lclBestVec.x) { // either top or bottom, need to search the left or right lclSearchPatt[4].x = (int16) (-step); lclSearchPatt[4].y = (int16) (lclBestVec.y - centerVec.y); lclSearchPatt[5].x = (int16) (step); lclSearchPatt[5].y = (int16) (lclBestVec.y - centerVec.y); } else { // either left or right, need to search the top or bottom lclSearchPatt[4].x = (int16) (lclBestVec.x - centerVec.x); lclSearchPatt[4].y = (int16) (-step); lclSearchPatt[5].x = (int16) (lclBestVec.x - centerVec.x); lclSearchPatt[5].y = (int16) (step); } } } } } *bestVec = lclBestVec; *bestSad = lclBestSad;}/* * MergeTree * * Parameters: * mrPairs Stores 1 pair of (ref + mv) for each block in MB, * no matter how the MB is partitioned. * interMode Inter-prediction mode for the MB * * Function: * Check if all the partitions have the same MV and ref. If it is, change * the mode to MOT_16x16, so it can be skipped if other conditions allow. * Sometimes, an MB or sub-MB can be separated into multiple partitions * but all the partitions have the same motion vector. Sometimes it is * due to the greedy search, and they should be merged. Sometimes * encoding multiple motion vectors can cost less bits because of some * prediction rules favor this particular separation. * * Returns: * - */int MergeTree(blkState_s *mrPairs, int *interMode){ int i; int merged; int newInterMode; newInterMode = *interMode; merged = 1; if (*interMode == MOT_8x8) { for (i = 0; i < 16; i ++) { if (mrPairs[0].mv.x != mrPairs[i].mv.x || mrPairs[0].mv.y != mrPairs[i].mv.y || mrPairs[0].ref != mrPairs[i].ref) { merged = 0; break; } } } else { if (*interMode == MOT_16x8) { if (mrPairs[0].mv.x != mrPairs[8].mv.x || mrPairs[0].mv.y != mrPairs[8].mv.y || mrPairs[0].ref != mrPairs[8].ref) merged = 0; } if (*interMode == MOT_8x16) { if (mrPairs[0].mv.x != mrPairs[2].mv.x || mrPairs[0].mv.y != mrPairs[2].mv.y || mrPairs[0].ref != mrPairs[2].ref) merged = 0; } } // merge has happened at the MB level if (merged) *interMode = MOT_16x16; return merged;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -