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

📄 mcomp.c

📁 linux下的一款播放器
💻 C
📖 第 1 页 / 共 5 页
字号:
}// MotionComp263 - perform half-pixel motion compensation for H.263extern void MotionComp263( MACROBLOCK_DESCR * mb, // Describes block to be motion-compensated                            PICTURE * prevPic,  // Describes previous picture used to form MC                            PICTURE * pic       // Output picture where MC block is placed                            ){    int     row, col, cX, cY, picOffset, hdim, nhor, nvert;    PIXEL   * source, * dest;	void (*pMC) ( int hSize, int vSize, PIXEL *in, PIXEL *out, int hdim, int mvX, int mvY);#if defined(COMPILE_MMX)	if(cpuid_is_mmx_motion_on()) {		//do mmx if compiler switch AND initialized AND detected		pMC = mcMMX;	} else #endif	{		pMC = mc;	}    // Compute luma pointers    col = 16 * mb->x;    row = 16 * mb->y;    hdim = pic->y.hoffset;    nhor = pic->y.nhor, nvert = pic->y.nvert;    picOffset = col + row * hdim;    dest = pic->y.ptr + picOffset;          // Point to output luma    source = prevPic->y.ptr + picOffset;    // Point to input luma (without motion comp)    // Do motion compensation for luma    if (mb->mtype == MTYPE263_INTER4V) {    // 4 motion vectors        // Upper left block        if (PointingOutside( col, col+7, row, row+7, mb->blkMvX[UPPER_LEFT_BLK],                             mb->blkMvY[UPPER_LEFT_BLK], nhor, nvert )  ==  NO) {            pMC( 8, 8, source, dest, hdim,                         mb->blkMvX[UPPER_LEFT_BLK], mb->blkMvY[UPPER_LEFT_BLK] );        } else {            limitMC( 8, 8, source, dest, hdim,                        mb->blkMvX[UPPER_LEFT_BLK], mb->blkMvY[UPPER_LEFT_BLK],                        -col, nhor - 1 - col, -row, nvert - 1 - row );        }        // Upper right block        if (PointingOutside( col+8, col+15, row, row+7, mb->blkMvX[UPPER_RIGHT_BLK],                             mb->blkMvY[UPPER_RIGHT_BLK], nhor, nvert )  ==  NO) {            pMC( 8, 8, source + 8, dest + 8, hdim,                        mb->blkMvX[UPPER_RIGHT_BLK], mb->blkMvY[UPPER_RIGHT_BLK] );        } else {            limitMC( 8, 8, source + 8, dest + 8, hdim,                        mb->blkMvX[UPPER_RIGHT_BLK], mb->blkMvY[UPPER_RIGHT_BLK],                        -col - 8, nhor - 1 - col - 8, -row, nvert - 1 - row );        }        // Lower left block        source += 8 * hdim;   // Advance 8 lines        dest += 8 * hdim;        if (PointingOutside( col, col+7, row+8, row+15, mb->blkMvX[LOWER_LEFT_BLK],                             mb->blkMvY[LOWER_LEFT_BLK], nhor, nvert )  ==  NO) {            pMC( 8, 8, source, dest, hdim,                        mb->blkMvX[LOWER_LEFT_BLK], mb->blkMvY[LOWER_LEFT_BLK] );        } else {            limitMC( 8, 8, source, dest, hdim,                        mb->blkMvX[LOWER_LEFT_BLK], mb->blkMvY[LOWER_LEFT_BLK],                        -col, nhor - 1 - col, -row - 8, nvert - 1 - row - 8 );        }        // Lower right block        if (PointingOutside( col+8, col+15, row+8, row+15, mb->blkMvX[LOWER_RIGHT_BLK],                            mb->blkMvY[LOWER_RIGHT_BLK], nhor, nvert )  ==  NO) {            pMC( 8, 8, source + 8, dest + 8, hdim,                        mb->blkMvX[LOWER_RIGHT_BLK], mb->blkMvY[LOWER_RIGHT_BLK] );        } else {            limitMC( 8, 8, source + 8, dest + 8, hdim,                        mb->blkMvX[LOWER_RIGHT_BLK], mb->blkMvY[LOWER_RIGHT_BLK],                        -col - 8, nhor - 1 - col - 8, -row - 8, nvert - 1 - row - 8 );        }        // Compute chroma mv        cX = chromaMvComp4V( mb->blkMvX );        cY = chromaMvComp4V( mb->blkMvY );        } else {    // One motion vector        if (PointingOutside( col, col+15, row, row+15, mb->mv_x, mb->mv_y,                                nhor, nvert )  ==  NO) {            pMC( 16, 16, source, dest, hdim, mb->mv_x, mb->mv_y );        } else {    // Pointing outside            limitMC( 16, 16, source, dest, hdim, mb->mv_x, mb->mv_y,                        -col, nhor - 1 - col, -row, nvert - 1 - row );        }        // Compute chroma mv        cX = chromaMVComp( mb->mv_x );        cY = chromaMVComp( mb->mv_y );    }        // Do motion compensation for chroma    if (pic->color) {        // Compute chroma pointers        col = 8 * mb->x;        row = 8 * mb->y;        hdim = pic->cb.hoffset;        nhor = pic->cb.nhor, nvert = pic->cb.nvert;        picOffset = col + row * hdim;        if (PointingOutside( col, col+7, row, row+7, cX, cY, nhor, nvert )  ==  NO) {            pMC( 8, 8, prevPic->cb.ptr + picOffset, pic->cb.ptr + picOffset, hdim, cX, cY );            pMC( 8, 8, prevPic->cr.ptr + picOffset, pic->cr.ptr + picOffset, hdim, cX, cY );        } else {            limitMC( 8, 8, prevPic->cb.ptr + picOffset, pic->cb.ptr + picOffset,                    hdim, cX, cY, -col, nhor - 1 - col, -row, nvert - 1 - row );            limitMC( 8, 8, prevPic->cr.ptr + picOffset, pic->cr.ptr + picOffset,                    hdim, cX, cY, -col, nhor - 1 - col, -row, nvert - 1 - row );        }    }    return;}// printBlk - for debugging/*static void printBlk( int hSize, int vSize, PIXEL *p, int hdim){    int i,j;        for (i = 0; i < vSize; ++i) {        for (j = 0; j < hSize; ++j) {            printf(" %3d", *(p + j));        }        printf("\n");        p += hdim;    }    return;}*/// Enumerate array of motion vectors#define LEFT        (0)#define TOP         (1)#define RIGHT       (2)#define BOTTOM      (3)// Do overlapped motion comp. for lumaextern void OverlapMC( MACROBLOCK_DESCR * mb,   // Describes block to be motion-compensated                        int     PBframe,    // Non-zero if PB frame                        PICTURE * prevPic,  // Describes previous picture used to form MC                        PICTURE * pic,      // Output picture where MC block is placed                        int     mbWidth,    // Macroblocks per row                        int     mbOffset,   // Row offset; (mb-mbOffset) is neighbor on top                        int     overlap[4]  // Returns YES or NO to indicate whether overlap                                            // was done in each 8x8 subblock                        ){    int left, top, right, bottom, mvX, mvY;    int borderMv[4][2]; // motion vectors for neighbors (left, top, right, bottom)        if (mb->mtype == MTYPE263_INTER4V) {        // Upper left block        mvX = mb->blkMvX[UPPER_LEFT_BLK];        mvY = mb->blkMvY[UPPER_LEFT_BLK];        if (mb->x == 0)  left = NO;        else  left = mvDiff( mvX, mvY, mb-1, UPPER_RIGHT_BLK, PBframe, borderMv[LEFT] );        if (mb->y == 0)  top = NO;        else  top = mvDiff( mvX, mvY, mb-mbOffset, LOWER_LEFT_BLK, PBframe, borderMv[TOP] );        right = mvDiff( mvX, mvY, mb, UPPER_RIGHT_BLK, PBframe, borderMv[RIGHT] );        bottom = mvDiff( mvX, mvY, mb, LOWER_LEFT_BLK, PBframe, borderMv[BOTTOM] );        if (left == YES || right == YES || top == YES || bottom == YES) {            doOverlapMC( UPPER_LEFT_BLK, mb, prevPic, pic, borderMv, left,top,right,bottom);            overlap[UPPER_LEFT_BLK] = YES;        } else {            overlap[UPPER_LEFT_BLK] = NO;        }        // Upper right block        mvX = mb->blkMvX[UPPER_RIGHT_BLK];        mvY = mb->blkMvY[UPPER_RIGHT_BLK];        left = mvDiff( mvX, mvY, mb, UPPER_LEFT_BLK, PBframe, borderMv[LEFT] );        if (mb->y == 0)  top = NO;        else  top = mvDiff( mvX, mvY, mb-mbOffset, LOWER_RIGHT_BLK, PBframe, borderMv[TOP] );        if (mb->x == mbWidth-1)  right = NO;        else  right = mvDiff( mvX, mvY, mb+1, UPPER_LEFT_BLK, PBframe, borderMv[RIGHT] );        bottom = mvDiff( mvX, mvY, mb, LOWER_RIGHT_BLK, PBframe, borderMv[BOTTOM] );        if (left == YES || right == YES || top == YES || bottom == YES) {            doOverlapMC( UPPER_RIGHT_BLK, mb, prevPic, pic, borderMv, left,top,right,bottom);            overlap[UPPER_RIGHT_BLK] = YES;        } else {            overlap[UPPER_RIGHT_BLK] = NO;        }        // Lower left block        mvX = mb->blkMvX[LOWER_LEFT_BLK];        mvY = mb->blkMvY[LOWER_LEFT_BLK];        if (mb->x == 0)  left = NO;        else  left = mvDiff( mvX, mvY, mb-1, LOWER_RIGHT_BLK, PBframe, borderMv[LEFT] );        top = mvDiff( mvX, mvY, mb, UPPER_LEFT_BLK, PBframe, borderMv[TOP] );        right = mvDiff( mvX, mvY, mb, LOWER_RIGHT_BLK, PBframe, borderMv[RIGHT] );        if (left == YES || right == YES || top == YES) {            doOverlapMC( LOWER_LEFT_BLK, mb, prevPic, pic, borderMv, left,top,right,NO);            overlap[LOWER_LEFT_BLK] = YES;        } else {            overlap[LOWER_LEFT_BLK] = NO;        }        // Lower right block        mvX = mb->blkMvX[LOWER_RIGHT_BLK];        mvY = mb->blkMvY[LOWER_RIGHT_BLK];        left = mvDiff( mvX, mvY, mb, LOWER_LEFT_BLK, PBframe, borderMv[LEFT] );        top = mvDiff( mvX, mvY, mb, UPPER_RIGHT_BLK, PBframe, borderMv[TOP] );        if (mb->x == mbWidth-1)  right = NO;        else  right = mvDiff( mvX, mvY, mb+1, LOWER_LEFT_BLK, PBframe, borderMv[RIGHT] );        if (left == YES || right == YES || top == YES) {            doOverlapMC( LOWER_RIGHT_BLK, mb, prevPic, pic, borderMv, left,top,right,NO);            overlap[LOWER_RIGHT_BLK] = YES;        } else {            overlap[LOWER_RIGHT_BLK] = NO;        }            } else {    // One motion vector for current macroblock; neighbors can be INTER4V        mvX = mb->mv_x;        mvY = mb->mv_y;        // Upper left block        if (mb->x == 0)  left = NO;        else  left = mvDiff( mvX, mvY, mb-1, UPPER_RIGHT_BLK, PBframe, borderMv[LEFT] );        if (mb->y == 0)  top = NO;        else  top = mvDiff( mvX, mvY, mb-mbOffset, LOWER_LEFT_BLK, PBframe, borderMv[TOP] );        if (left == YES || top == YES) {            doOverlapMC( UPPER_LEFT_BLK, mb, prevPic, pic, borderMv, left,top,NO,NO);            overlap[UPPER_LEFT_BLK] = YES;        } else {            overlap[UPPER_LEFT_BLK] = NO;        }        // Upper right block        if (mb->y == 0)  top = NO;        else  top = mvDiff( mvX, mvY, mb-mbOffset, LOWER_RIGHT_BLK, PBframe, borderMv[TOP] );        if (mb->x == mbWidth-1)  right = NO;        else  right = mvDiff( mvX, mvY, mb+1, UPPER_LEFT_BLK, PBframe, borderMv[RIGHT] );        if (right == YES || top == YES) {            doOverlapMC( UPPER_RIGHT_BLK, mb, prevPic, pic, borderMv, NO,top,right,NO);            overlap[UPPER_RIGHT_BLK] = YES;        } else {            overlap[UPPER_RIGHT_BLK] = NO;        }        // Lower left block        if (mb->x == 0)  left = NO;        else  left = mvDiff( mvX, mvY, mb-1, LOWER_RIGHT_BLK, PBframe, borderMv[LEFT] );        if (left == YES) {            doOverlapMC( LOWER_LEFT_BLK, mb, prevPic, pic, borderMv, left,NO,NO,NO);            overlap[LOWER_LEFT_BLK] = YES;        } else {            overlap[LOWER_LEFT_BLK] = NO;        }        // Lower right block        if (mb->x == mbWidth-1)  right = NO;        else  right = mvDiff( mvX, mvY, mb+1, LOWER_LEFT_BLK, PBframe, borderMv[RIGHT] );        if (right == YES) {            doOverlapMC( LOWER_RIGHT_BLK, mb, prevPic, pic, borderMv, NO,NO,right,NO);            overlap[LOWER_RIGHT_BLK] = YES;        } else {            overlap[LOWER_RIGHT_BLK] = NO;        }    }    return;}// PointingOutside - determine whether motion-comp routine needs to worry about //  the borders of the previous picture (use edge pixels instead of non-existent//  pixels "outside" the border of the previous picture).//  Returns YES if the motion-compensated block needs pixels outside the previous//  picture; NO if picture boundary is not crossed.extern int PointingOutside( int col1, int col2, // First and last column of block                            int row1, int row2, // First and last row of block                            int mvX, int mvY,   // Motion vector; one fractional bit                            int nCols, int nRows    // Picture size                            ){    if (col1 + (mvX >> 1)  <  0)            // Check left border        return( YES );    if (col2 + ((mvX + 1) >> 1)  >=  nCols) // Check right border        return( YES );    if (row1 + (mvY >> 1)  <  0)            // Check top border        return( YES );    if (row2 + ((mvY + 1) >> 1)  >=  nRows) // Check bottom border        return( YES );    return( NO );}//  PredBframe - Form prediction for B-frameextern void PredBframe( MACROBLOCK_DESCR * mb,  // Macroblock to be predicted                        PICTURE * prevPic,      // Prev. picture (forward pred)                        PICTURE * nextPic,      // Next P-picture (backward pred)                        PICTURE * Bpic          // Output picture where pred is placed                        ){    int     i;    S8      saveMvX[4], saveMvY[4];    // Perform backward prediction    if (mb->mtype == MTYPE263_INTER4V) {        for (i = 0; i < 4; ++i) {            saveMvX[i] = mb->blkMvX[i];            mb->blkMvX[i] = mb->blkMvBx[i];            saveMvY[i] = mb->blkMvY[i];            mb->blkMvY[i] = mb->blkMvBy[i];        }    } else {        saveMvX[0] = mb->mv_x;        mb->mv_x = mb->blkMvBx[0];        saveMvY[0] = mb->mv_y;        mb->mv_y = mb->blkMvBy[0];    }    MotionComp263( mb, nextPic, Bpic );    // Save backward prediction in temporary area    saveBackwardPred( mb, Bpic );    // Perform forward prediction    if (mb->mtype == MTYPE263_INTER4V) {        for (i = 0; i < 4; ++i) {            mb->blkMvX[i] = mb->blkMvFx[i];            mb->blkMvY[i] = mb->blkMvFy[i];        }    } else {        mb->mv_x = mb->blkMvFx[0];        mb->mv_y = mb->blkMvFy[0];    }    MotionComp263( mb, prevPic, Bpic );    // Restore parameters    if (mb->mtype == MTYPE263_INTER4V) {        for (i = 0; i < 4; ++i) {            mb->blkMvX[i] = saveMvX[i];            mb->blkMvY[i] = saveMvY[i];        }    } else {        mb->mv_x = saveMvX[0];        mb->mv_y = saveMvY[0];    }    // Average forward and backward prediction    averageForBack( mb, Bpic );}

⌨️ 快捷键说明

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