⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsearch.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 3 页
字号:
                /* STEP 3 */    if ( interpErr <= interpErr2 ) {    newfmy = *fmy;    newfmx = *fmx;    }    else    {    newbmy = *bmy;    newbmx = *bmx;    interpErr = interpErr2;    }    if ( interpErr <= forwardErr ) {    if ( interpErr <= backErr ) {        *fmy = newfmy;        *fmx = newfmx;        *bmy = newbmy;        *bmx = newbmx;        return MOTION_INTERPOLATE;    }    else        return MOTION_BACKWARD;    } else if ( forwardErr <= backErr ) {    return MOTION_FORWARD;    } else {    return MOTION_BACKWARD;    }}/*===========================================================================* * * BMotionSearchExhaust * *  does an exhaustive search for B-frame motion vectors *  see BMotionSearch for generic description * * DESCRIPTION: *  1)  find best backward and forward vectors *  2)  use exhaustive search to find best interpolating vectors *  3)  return the best of the 3 choices * *===========================================================================*/static intBMotionSearchExhaust(currentBlock, prev, next, by, bx, fmy, fmx, bmy, bmx,            oldMode)    LumBlock currentBlock;    MpegFrame *prev;    MpegFrame *next;    int by;    int bx;    int *fmy;    int *fmx;    int *bmy;    int *bmx;    int oldMode;{    register int mx, my;    int32 diff, bestDiff;    int     stepSize;    LumBlock    forwardBlock;    int32   forwardErr, backErr;    int     newbmy, newbmx;    int     leftMY, leftMX;    int     rightMY, rightMX;    boolean result;                /* STEP 1 */    BMotionSearchNoInterp(currentBlock, prev, next, by, bx, fmy, fmx,              &forwardErr, bmy, bmx, &backErr, FALSE);    if ( forwardErr <= backErr ) {        bestDiff = forwardErr;    result = MOTION_FORWARD;    }    else    {        bestDiff = backErr;    result = MOTION_BACKWARD;    }                /* STEP 2 */    stepSize = (pixelFullSearch ? 2 : 1);    COMPUTE_MOTION_BOUNDARY(by,bx,stepSize,leftMY,leftMX,rightMY,rightMX);    if ( searchRangeB < rightMY ) {    rightMY = searchRangeB;    }    if ( searchRangeB < rightMX ) {    rightMX = searchRangeB;    }    for ( my = -searchRangeB; my < rightMY; my += stepSize ) {    if ( my < leftMY ) {        continue;    }    for ( mx = -searchRangeB; mx < rightMX; mx += stepSize ) {        if ( mx < leftMX ) {        continue;        }        ComputeBMotionLumBlock(prev, next, by, bx, MOTION_FORWARD,               my, mx, 0, 0, forwardBlock);        newbmy = my;    newbmx = mx;        diff = FindBestMatch(forwardBlock, currentBlock, next, by, bx,                 &newbmy, &newbmx, bestDiff, searchRangeB);        if ( diff < bestDiff ) {        *fmy = my;        *fmx = mx;        *bmy = newbmy;        *bmx = newbmx;        bestDiff = diff;        result = MOTION_INTERPOLATE;        }    }    }    return result;}/*===========================================================================* * * FindBestMatch * *  given a motion-compensated block in one direction, tries to find *  the best motion vector in the opposite direction to match it * * RETURNS: the best vector (*motionY, *motionX), and the corresponding *      error is returned if it is better than bestSoFar.  If not, *      then a number greater than bestSoFar is returned and *      (*motionY, *motionX) has no meaning. * * SIDE EFFECTS:  none * *===========================================================================*/static int32FindBestMatch(block, currentBlock, prev, by, bx, motionY, motionX, bestSoFar, searchRange)    LumBlock block;    LumBlock currentBlock;    MpegFrame *prev;    int by;    int bx;    int *motionY;    int *motionX;    int32 bestSoFar;    int searchRange;{    int32   result;    switch(psearchAlg) {    case PSEARCH_SUBSAMPLE:        result = FindBestMatchSubSample(block, currentBlock, prev, by, bx,                        motionY, motionX, bestSoFar, searchRange);        break;    case PSEARCH_EXHAUSTIVE:        result = FindBestMatchExhaust(block, currentBlock, prev, by, bx,                      motionY, motionX, bestSoFar, searchRange);        break;    case PSEARCH_LOGARITHMIC:        result = FindBestMatchLogarithmic(block, currentBlock, prev, by, bx,                          motionY, motionX, bestSoFar, searchRange);        break;    case PSEARCH_TWOLEVEL:        result = FindBestMatchTwoLevel(block, currentBlock, prev, by, bx,                       motionY, motionX, bestSoFar, searchRange);        break;    default:        fprintf(stderr, "ERROR:  Illegal P-search alg %d\n", psearchAlg);        exit(1);    }    return result;}/*===========================================================================* * * FindBestMatchExhaust * *  tries to find matching motion vector *  see FindBestMatch for generic description * * DESCRIPTION:  uses an exhaustive search * *===========================================================================*/static int32FindBestMatchExhaust(block, currentBlock, prev, by, bx, motionY, motionX,             bestSoFar, searchRange)    LumBlock block;    LumBlock currentBlock;    MpegFrame *prev;    int by;    int bx;    int *motionY;    int *motionX;    int32 bestSoFar;    int searchRange;{    register int mx, my;    int32 diff, bestDiff;    int     stepSize;    int     leftMY, leftMX;    int     rightMY, rightMX;    int     distance;    int     tempRightMY, tempRightMX;    boolean changed = FALSE;    stepSize = (pixelFullSearch ? 2 : 1);    COMPUTE_MOTION_BOUNDARY(by,bx,stepSize,leftMY,leftMX,rightMY,rightMX);    /* try old motion vector first */    if ( VALID_MOTION(*motionY, *motionX) ) {    bestDiff = LumAddMotionError(currentBlock, block, prev, by, bx,                     *motionY, *motionX, bestSoFar);    if ( bestSoFar < bestDiff ) {        bestDiff = bestSoFar;    }    }    else    {    *motionY = 0;    *motionX = 0;    bestDiff = bestSoFar;    }/* maybe should try spiral pattern centered around  prev motion vector? */    /* 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 = LumAddMotionError(currentBlock, block, prev, by, bx,                     my, mx, bestDiff);        if ( diff < bestDiff ) {            *motionY = my;            *motionX = 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 = LumAddMotionError(currentBlock, block, prev, by, bx,                     my, mx, bestDiff);        if ( diff < bestDiff ) {            *motionY = my;            *motionX = mx;            bestDiff = diff;            changed = TRUE;        }        }    }    }    if ( ! changed ) {    bestDiff++;    }    return bestDiff;}/*===========================================================================* * * FindBestMatchTwoLevel * *  tries to find matching motion vector *  see FindBestMatch for generic description * * DESCRIPTION:  uses an exhaustive full-pixel search, then looks at *       neighboring half-pixels * *===========================================================================*/static int32FindBestMatchTwoLevel(block, currentBlock, prev, by, bx, motionY, motionX,              bestSoFar, searchRange)    LumBlock block;    LumBlock currentBlock;    MpegFrame *prev;    int by;    int bx;    int *motionY;    int *motionX;    int32 bestSoFar;    int searchRange;{    register int mx, my;    int32 diff, bestDiff;    int     leftMY, leftMX;    int     rightMY, rightMX;    int     distance;    int     tempRightMY, tempRightMX;    boolean changed = FALSE;    int     yOffset, xOffset;    /* exhaustive full-pixel search first */    COMPUTE_MOTION_BOUNDARY(by,bx,2,leftMY,leftMX,rightMY,rightMX);    rightMY--;    rightMX--;    /* convert vector into full-pixel vector */    if ( *motionY > 0 ) {    if ( ((*motionY) % 2) == 1 ) {        (*motionY)--;    }    } else if ( ((-(*motionY)) % 2) == 1 ) {    (*motionY)++;    }    if ( *motionX > 0 ) {    if ( ((*motionX) % 2) == 1 ) {        (*motionX)--;    }    } else if ( ((-(*motionX)) % 2) == 1 ) {    (*motionX)++;    }    /* try old motion vector first */    if ( VALID_MOTION(*motionY, *motionX) ) {    bestDiff = LumAddMotionError(currentBlock, block, prev, by, bx,                     *motionY, *motionX, bestSoFar);    if ( bestSoFar < bestDiff ) {        bestDiff = bestSoFar;    }    }    else    {    *motionY = 0;    *motionX = 0;    bestDiff = bestSoFar;    }    rightMY++;    rightMX++;/* maybe should try spiral pattern centered around  prev motion vector? */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -