📄 psearch.c
字号:
bestDiff = INT_MAX; for( spacing = searchRange; spacing >= stepSize; ) { if ( stepSize == 2 ) { /* make sure spacing is even */ if ( spacing == 2 ) spacing = 0; else { spacing = (spacing+1)/2; if ( (spacing % 2) != 0 ) spacing--; } } else { if ( spacing == 1 ) { spacing = 0; } else spacing = (spacing+1)/2; } if (spacing >= stepSize) findBestSpaced(max(minMY, motionY - spacing), max(minMX, motionX - spacing), min(maxMY, motionY + spacing + 1), min(maxMX, motionX + spacing + 1), spacing, currentBlock, prev, by, bx, &bestDiff, &motionY, &motionX); } { int diff; /* check old motion -- see if it's better */ if ( (*motionYP >= minMY) && (*motionYP < maxMY) && (*motionXP >= minMX) && (*motionXP < maxMX) ) { diff = LumMotionError(currentBlock, prev, by, bx, *motionYP, *motionXP, bestDiff); } else diff = INT_MAX; if ( bestDiff < diff ) { *motionYP = motionY; *motionXP = motionX; } else bestDiff = diff; } return bestDiff;}/*===========================================================================* * * PLocalSearch * * uses local exhaustive search to compute the P-frame vector * * RETURNS: motion vector * * SIDE EFFECTS: none * *===========================================================================*/intPLocalSearch(LumBlock currentBlock, MpegFrame * prev, int by, int bx, int * motionYP, int * motionXP, int bestSoFar, int searchRange){ register int mx, my; int diff, bestDiff; int stepSize; int leftMY, leftMX; int rightMY, rightMX; int distance; int tempRightMY, tempRightMX; stepSize = (pixelFullSearch ? 2 : 1); COMPUTE_MOTION_BOUNDARY(by,bx,stepSize,leftMY,leftMX,rightMY,rightMX); /* try old motion vector first */ if ( VALID_MOTION(*motionYP, *motionXP) ) { bestDiff = LumMotionError(currentBlock, prev, by, bx, *motionYP, *motionXP, bestSoFar); if ( bestSoFar < bestDiff ) { bestDiff = bestSoFar; } } else { *motionYP = 0; *motionXP = 0; bestDiff = bestSoFar; } /* try a spiral pattern */ for ( distance = stepSize; distance <= searchRange; distance += stepSize ) { tempRightMY = rightMY; if ( distance < tempRightMY ) { tempRightMY = distance; } tempRightMX = rightMX; if ( distance < tempRightMX ) { tempRightMX = distance; } /* do top, bottom */ for ( my = -distance; my < tempRightMY; my += max(tempRightMY+distance-stepSize, stepSize) ) { if ( my < leftMY ) { continue; } for ( mx = -distance; mx < tempRightMX; mx += stepSize ) { if ( mx < leftMX ) { continue; } diff = LumMotionError(currentBlock, prev, by, bx, my, mx, bestDiff); if ( diff < bestDiff ) { *motionYP = my; *motionXP = mx; bestDiff = diff; } } } /* do left, right */ for ( mx = -distance; mx < tempRightMX; mx += max(tempRightMX+distance-stepSize, stepSize) ) { if ( mx < leftMX ) { continue; } for ( my = -distance+stepSize; my < tempRightMY-stepSize; my += stepSize ) { if ( my < leftMY ) { continue; } diff = LumMotionError(currentBlock, prev, by, bx, my, mx, bestDiff); if ( diff < bestDiff ) { *motionYP = my; *motionXP = mx; bestDiff = diff; } } } } return bestDiff;}/*===========================================================================* * * PTwoLevelSearch * * uses two-level search to compute the P-frame vector * first does exhaustive full-pixel search, then looks at neighboring * half-pixel motion vectors * * RETURNS: motion vector * * SIDE EFFECTS: none * *===========================================================================*/intPTwoLevelSearch(LumBlock currentBlock, MpegFrame * prev, int by, int bx, int * motionYP, int * motionXP, int bestSoFar, int searchRange){ register int mx, my; register int loopInc; int diff, bestDiff; int leftMY, leftMX; int rightMY, rightMX; int distance; int tempRightMY, tempRightMX; int xOffset, yOffset; /* exhaustive full-pixel search first */ COMPUTE_MOTION_BOUNDARY(by,bx,2,leftMY,leftMX,rightMY,rightMX); rightMY--; rightMX--; /* convert vector into full-pixel vector */ if ( *motionYP > 0 ) { if ( ((*motionYP) % 2) == 1 ) { (*motionYP)--; } } else if ( ((-(*motionYP)) % 2) == 1 ) { (*motionYP)++; } if ( *motionXP > 0 ) { if ( ((*motionXP) % 2) == 1 ) { (*motionXP)--; } } else if ( ((-(*motionXP)) % 2) == 1 ) { (*motionXP)++; } /* try old motion vector first */ if ( VALID_MOTION(*motionYP, *motionXP) ) { bestDiff = LumMotionError(currentBlock, prev, by, bx, *motionYP, *motionXP, bestSoFar); if ( bestSoFar < bestDiff ) { bestDiff = bestSoFar; } } else { *motionYP = 0; *motionXP = 0; bestDiff = bestSoFar; } rightMY++; rightMX++; /* try a spiral pattern */ for ( distance = 2; distance <= searchRange; distance += 2 ) { tempRightMY = rightMY; if ( distance < tempRightMY ) { tempRightMY = distance; } tempRightMX = rightMX; if ( distance < tempRightMX ) { tempRightMX = distance; } /* do top, bottom */ loopInc = max(tempRightMY+distance-2, 2); for ( my = -distance; my < tempRightMY; my += loopInc ) { if ( my < leftMY ) { continue; } for ( mx = -distance; mx < tempRightMX; mx += 2 ) { if ( mx < leftMX ) { continue; } diff = LumMotionError(currentBlock, prev, by, bx, my, mx, bestDiff); if ( diff < bestDiff ) { *motionYP = my; *motionXP = mx; bestDiff = diff; } } } /* do left, right */ loopInc = max(tempRightMX+distance-2, 2); for ( mx = -distance; mx < tempRightMX; mx += loopInc ) { if ( mx < leftMX ) { continue; } for ( my = -distance+2; my < tempRightMY-2; my += 2 ) { if ( my < leftMY ) { continue; } diff = LumMotionError(currentBlock, prev, by, bx, my, mx, bestDiff); if ( diff < bestDiff ) { *motionYP = my; *motionXP = mx; bestDiff = diff; } } } } /* now look at neighboring half-pixels */ my = *motionYP; mx = *motionXP; rightMY--; rightMX--; for ( yOffset = -1; yOffset <= 1; yOffset++ ) { for ( xOffset = -1; xOffset <= 1; xOffset++ ) { if ( (yOffset == 0) && (xOffset == 0) ) continue; if ( VALID_MOTION(my+yOffset, mx+xOffset) && ((diff = LumMotionError(currentBlock, prev, by, bx, my+yOffset, mx+xOffset, bestDiff)) < bestDiff) ) { *motionYP = my+yOffset; *motionXP = mx+xOffset; bestDiff = diff; } } } return bestDiff;}voidShowPMVHistogram(fpointer) FILE *fpointer;{ register int x, y; int *columnTotals; int rowTotal; columnTotals = (int *) calloc(2*searchRangeP+3, sizeof(int));#ifdef COMPLETE_DISPLAY fprintf(fpointer, " "); for ( y = 0; y < 2*searchRange+3; y++ ) { fprintf(fpointer, "%3d ", y-searchRangeP-1); } fprintf(fpointer, "\n");#endif for ( x = 0; x < 2*searchRangeP+3; x++ ) {#ifdef COMPLETE_DISPLAY fprintf(fpointer, "%3d ", x-searchRangeP-1);#endif rowTotal = 0; for ( y = 0; y < 2*searchRangeP+3; y++ ) { fprintf(fpointer, "%3d ", pmvHistogram[x][y]); rowTotal += pmvHistogram[x][y]; columnTotals[y] += pmvHistogram[x][y]; }#ifdef COMPLETE_DISPLAY fprintf(fpointer, "%4d\n", rowTotal);#else fprintf(fpointer, "\n");#endif }#ifdef COMPLETE_DISPLAY fprintf(fpointer, "Tot "); for ( y = 0; y < 2*searchRangeP+3; y++ ) { fprintf(fpointer, "%3d ", columnTotals[y]); }#endif fprintf(fpointer, "\n");}voidShowBBMVHistogram(fpointer) FILE *fpointer;{ register int x, y; int *columnTotals; int rowTotal; fprintf(fpointer, "B-frame Backwards:\n"); columnTotals = (int *) calloc(2*searchRangeB+3, sizeof(int));#ifdef COMPLETE_DISPLAY fprintf(fpointer, " "); for ( y = 0; y < 2*searchRangeB+3; y++ ) { fprintf(fpointer, "%3d ", y-searchRangeB-1); } fprintf(fpointer, "\n");#endif for ( x = 0; x < 2*searchRangeB+3; x++ ) {#ifdef COMPLETE_DISPLAY fprintf(fpointer, "%3d ", x-searchRangeB-1);#endif rowTotal = 0; for ( y = 0; y < 2*searchRangeB+3; y++ ) { fprintf(fpointer, "%3d ", bbmvHistogram[x][y]); rowTotal += bbmvHistogram[x][y]; columnTotals[y] += bbmvHistogram[x][y]; }#ifdef COMPLETE_DISPLAY fprintf(fpointer, "%4d\n", rowTotal);#else fprintf(fpointer, "\n");#endif }#ifdef COMPLETE_DISPLAY fprintf(fpointer, "Tot "); for ( y = 0; y < 2*searchRangeB+3; y++ ) { fprintf(fpointer, "%3d ", columnTotals[y]); }#endif fprintf(fpointer, "\n");}voidShowBFMVHistogram(fpointer) FILE *fpointer;{ register int x, y; int *columnTotals; int rowTotal; fprintf(fpointer, "B-frame Forwards:\n"); columnTotals = (int *) calloc(2*searchRangeB+3, sizeof(int));#ifdef COMPLETE_DISPLAY fprintf(fpointer, " "); for ( y = 0; y < 2*searchRangeB+3; y++ ) { fprintf(fpointer, "%3d ", y-searchRangeB-1); } fprintf(fpointer, "\n");#endif for ( x = 0; x < 2*searchRangeB+3; x++ ) {#ifdef COMPLETE_DISPLAY fprintf(fpointer, "%3d ", x-searchRangeB-1);#endif rowTotal = 0; for ( y = 0; y < 2*searchRangeB+3; y++ ) { fprintf(fpointer, "%3d ", bfmvHistogram[x][y]); rowTotal += bfmvHistogram[x][y]; columnTotals[y] += bfmvHistogram[x][y]; }#ifdef COMPLETE_DISPLAY fprintf(fpointer, "%4d\n", rowTotal);#else fprintf(fpointer, "\n");#endif }#ifdef COMPLETE_DISPLAY fprintf(fpointer, "Tot "); for ( y = 0; y < 2*searchRangeB+3; y++ ) { fprintf(fpointer, "%3d ", columnTotals[y]); }#endif fprintf(fpointer, "\n");}/* * Copyright (c) 1995 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. *//* * $Header: /u/smoot/md/mpeg_encode/RCS/psearch.c,v 1.9 1995/01/19 23:09:12 eyhung Exp $ * $Log: psearch.c,v $ * Revision 1.9 1995/01/19 23:09:12 eyhung * Changed copyrights * * Revision 1.9 1995/01/19 23:09:12 eyhung * Changed copyrights * * Revision 1.8 1994/12/07 00:40:36 smoot * Added seperate P and B search ranges * * Revision 1.7 1994/11/12 02:09:45 eyhung * full pixel bug * fixed on lines 512 and 563 * * Revision 1.6 1994/03/15 00:27:11 keving * nothing * * Revision 1.5 1993/12/22 19:19:01 keving * nothing * * Revision 1.4 1993/07/22 22:23:43 keving * nothing * * Revision 1.3 1993/06/30 20:06:09 keving * nothing * * Revision 1.2 1993/06/03 21:08:08 keving * nothing * * Revision 1.1 1993/03/02 18:27:05 keving * nothing * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -