📄 mcomp.c
字号:
if (borderMB->mtype == MTYPE263_INTER4V) { border[0] = borderMB->blkMvX[ subBlk ]; border[1] = borderMB->blkMvY[ subBlk ]; } else { border[0] = borderMB->mv_x; border[1] = borderMB->mv_y; if (borderMB->mtype >= MTYPE263_INTRA && PBframe == 0) { return( NO ); // No overlap with INTRA neighbor (except in PBframe) } } if (border[0] != mvX || border[1] != mvY) { return( YES ); } return( NO );}// median3 - return median of 3 valuesstatic int median3( int x[3] ){ int order[2]; if (x[1] < x[0]) { order[0] = x[1]; order[1] = x[0]; } else { order[0] = x[0]; order[1] = x[1]; } if (x[2] < order[0]) { return( order[0] ); } else if (x[2] < order[1]) { return( x[2] ); } return( order[1] );}// MvPred - Compute mv predictor (mvX,mvY) for block "blk" of macroblock mb[0].// blk = UPPER_LEFT_BLK, UPPER_RIGHT_BLK, LOWER_LEFT_BLK, LOWER_RIGHT_BLK,// or WHOLE_MACROBLOCK.// If horPredOnly=YES: don't use previous row of macroblocks in predictionextern void MvPred( MACROBLOCK_DESCR mb[], int blk, // specify block: UL, UR, LL, LR, or WHOLE int mbhor, // offset from previous row of MBs int horPredOnly, int *mvX, int *mvY ){ int x[3], y[3]; switch (blk) { case UPPER_RIGHT_BLK: x[0] = mb[0].blkMvX[UPPER_LEFT_BLK]; y[0] = mb[0].blkMvY[UPPER_LEFT_BLK]; if (horPredOnly == YES) { // Top border or sending GOB header to resync *mvX = x[0], *mvY = y[0]; } else { if (mb[-mbhor].mtype == MTYPE263_INTER4V) { x[1] = mb[-mbhor].blkMvX[LOWER_RIGHT_BLK]; y[1] = mb[-mbhor].blkMvY[LOWER_RIGHT_BLK]; } else { x[1] = mb[-mbhor].mv_x; y[1] = mb[-mbhor].mv_y; } if (mb[0].x == mbhor - 1) { // Right border x[2] = 0, y[2] = 0; } else if (mb[1-mbhor].mtype == MTYPE263_INTER4V) { x[2] = mb[1-mbhor].blkMvX[LOWER_LEFT_BLK]; y[2] = mb[1-mbhor].blkMvY[LOWER_LEFT_BLK]; } else { x[2] = mb[1-mbhor].mv_x; y[2] = mb[1-mbhor].mv_y; } *mvX = median3( x ); *mvY = median3( y ); } break; case LOWER_LEFT_BLK: if (mb[0].x == 0) { // Left border x[0] = 0, y[0] = 0; } else if (mb[-1].mtype == MTYPE263_INTER4V) { x[0] = mb[-1].blkMvX[LOWER_RIGHT_BLK]; y[0] = mb[-1].blkMvY[LOWER_RIGHT_BLK]; } else { x[0] = mb[-1].mv_x; y[0] = mb[-1].mv_y; } x[1] = mb[0].blkMvX[UPPER_LEFT_BLK]; y[1] = mb[0].blkMvY[UPPER_LEFT_BLK]; x[2] = mb[0].blkMvX[UPPER_RIGHT_BLK]; y[2] = mb[0].blkMvY[UPPER_RIGHT_BLK]; *mvX = median3( x ); *mvY = median3( y ); break; case LOWER_RIGHT_BLK: x[0] = mb[0].blkMvX[LOWER_LEFT_BLK]; y[0] = mb[0].blkMvY[LOWER_LEFT_BLK]; x[1] = mb[0].blkMvX[UPPER_LEFT_BLK]; y[1] = mb[0].blkMvY[UPPER_LEFT_BLK]; x[2] = mb[0].blkMvX[UPPER_RIGHT_BLK]; y[2] = mb[0].blkMvY[UPPER_RIGHT_BLK]; *mvX = median3( x ); *mvY = median3( y ); break; case WHOLE_MACROBLOCK: case UPPER_LEFT_BLK: default: if (mb[0].x == 0) { // Left border x[0] = 0, y[0] = 0; } else if (mb[-1].mtype == MTYPE263_INTER4V) { x[0] = mb[-1].blkMvX[UPPER_RIGHT_BLK]; y[0] = mb[-1].blkMvY[UPPER_RIGHT_BLK]; } else { x[0] = mb[-1].mv_x; y[0] = mb[-1].mv_y; } if (horPredOnly == YES) { // Top border or sending GOB header to resync *mvX = x[0], *mvY = y[0]; } else { if (mb[-mbhor].mtype == MTYPE263_INTER4V) { x[1] = mb[-mbhor].blkMvX[LOWER_LEFT_BLK]; y[1] = mb[-mbhor].blkMvY[LOWER_LEFT_BLK]; } else { x[1] = mb[-mbhor].mv_x; y[1] = mb[-mbhor].mv_y; } if (mb[0].x == mbhor - 1) { // Right border x[2] = 0, y[2] = 0; } else if (mb[1-mbhor].mtype == MTYPE263_INTER4V) { x[2] = mb[1-mbhor].blkMvX[LOWER_LEFT_BLK]; y[2] = mb[1-mbhor].blkMvY[LOWER_LEFT_BLK]; } else { x[2] = mb[1-mbhor].mv_x; y[2] = mb[1-mbhor].mv_y; } *mvX = median3( x ); *mvY = median3( y ); } break; } return;}// doOverlapMC - Perform overlapped motion compensation on 8x8 blockstatic void doOverlapMC( int subBlk, // Indicates subblock to process (UL, UR, LL, LR) MACROBLOCK_DESCR *mb, // Used to determine (x,y) coordinates for block PICTURE *prevPic, // Previous picture; used to create overlapping MC PICTURE *pic, // Contains non-overlapped MC on entry; returns overlapped MC int borderMv[4][2], // Motion vectors for adjacent blocks (L,Top,R,Bottom) int left, // If YES, overlap using LEFT mv int top, // If YES, overlap using TOP mv int right, // If YES, overlap using RIGHT mv int bottom // If YES, overlap using BOTTOM mv ){#define LEFT_ADDR (0)#define RIGHT_ADDR (LEFT_ADDR + 4)#define TOP_OFFSET (8)#define TOP_ADDR (LEFT_ADDR + TOP_OFFSET)#define MAX_HDIM (352) static PIXEL p[8 * MAX_HDIM]; // MC predictions using neighboring vectors // Only using first 16 columns; line offset chosen to be same as for pictures int row, col, picOffset, hdim, nhor, nvert, *mv; 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; if (subBlk == UPPER_RIGHT_BLK || subBlk == LOWER_RIGHT_BLK) col += 8; if (subBlk == LOWER_LEFT_BLK || subBlk == LOWER_RIGHT_BLK) row += 8; 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 (non-overlapped MC) source = prevPic->y.ptr + picOffset; // Point to input luma (without motion comp) if (hdim > MAX_HDIM) { H261ErrMsg("doOverlapMC - Increase size of internal array"); exit(0); } // Create motion compensated blocks using neighboring motion vectors if (left == YES) { // Produce left 4 columns mv = borderMv[LEFT]; if (PointingOutside( col, col+3, row, row+7, *mv, *(mv+1), nhor, nvert) == NO) { pMC( 4,8, source, &p[LEFT_ADDR], hdim, *mv, *(mv+1) ); } else { limitMC( 4,8, source, &p[LEFT_ADDR], hdim, *mv, *(mv+1), -col, nhor - 1 - col, -row, nvert - 1 - row ); } } if (right == YES) { // Produce right 4 columns mv = borderMv[RIGHT]; if (PointingOutside( col+4, col+7, row, row+7, *mv, *(mv+1), nhor, nvert) == NO) { pMC( 4,8, source + 4, &p[RIGHT_ADDR], hdim, *mv, *(mv+1) ); } else { limitMC( 4,8, source + 4, &p[RIGHT_ADDR], hdim, *mv, *(mv+1), -col - 4, nhor - 1 - col - 4, -row, nvert - 1 - row ); } } if (top == YES) { // Produce top 4 rows mv = borderMv[TOP]; if (PointingOutside( col, col+7, row, row+3, *mv, *(mv+1), nhor, nvert) == NO) { pMC( 8,4, source, &p[TOP_ADDR], hdim, *mv, *(mv+1) ); } else { limitMC( 8,4, source, &p[TOP_ADDR], hdim, *mv, *(mv+1), -col, nhor - 1 - col, -row, nvert - 1 - row ); } } if (bottom == YES) { // Produce bottom 4 rows mv = borderMv[BOTTOM]; if (PointingOutside( col, col+7, row+4, row+7, *mv, *(mv+1), nhor, nvert) == NO) { pMC( 8,4, source + 4*hdim, &p[TOP_ADDR + 4*hdim], hdim, *mv, *(mv+1) ); } else { limitMC( 8,4, source + 4*hdim, &p[TOP_ADDR + 4*hdim], hdim, *mv, *(mv+1), -col, nhor - 1 - col, -row - 4, nvert - 1 - row - 4 ); } } // Produce weighted ("overlapped") MC prediction weigh8x4( dest, &p[LEFT_ADDR], hdim, top, left, right ); // Top 4 rows weigh8x4( dest + 7*hdim, &p[LEFT_ADDR + 7*hdim], -hdim, bottom, left, right ); // Bottom 4 rows return;}// weigh8x4static void weigh8x4( PIXEL *dest, PIXEL const *p, int hdim, int vert, int left, int right ){ if (vert == YES) { // Use top/bottom MV if (left == YES) { weighLeft_Vert( dest, &p[LEFT_ADDR], hdim ); } else { weighNoLeft_Vert( dest, &p[LEFT_ADDR], hdim ); } if (right == YES) { weighRight_Vert( dest + 4, &p[RIGHT_ADDR], hdim ); } else { weighNoRight_Vert( dest + 4, &p[RIGHT_ADDR], hdim ); } } else { if (left == YES) { weighLeft( dest, &p[LEFT_ADDR], hdim ); } if (right == YES) { weighRight( dest + 4, &p[RIGHT_ADDR], hdim ); } } return;}// weighLeft_Vert - Overlap three MC predictions for upper left 4x4 pixelsstatic void weighLeft_Vert( PIXEL *dest, // Non-overlapped MC; overlapped by this routine PIXEL const *p, // p: MC using left motion vector // &p[TOP_OFFSET]: MC using top/bottom MV int hdim ) // Line offset{ // First row dest[0] = (2 * dest[0] + p[0] + p[TOP_OFFSET + 0] + 2) >> 2; dest[1] = (5 * dest[1] + p[1] + 2 * p[TOP_OFFSET + 1] + 4) >> 3; dest[2] = (5 * dest[2] + p[2] + 2 * p[TOP_OFFSET + 2] + 4) >> 3; dest[3] = (5 * dest[3] + p[3] + 2 * p[TOP_OFFSET + 3] + 4) >> 3; // Second row dest += hdim, p += hdim; dest[0] = (5 * dest[0] + 2 * p[0] + p[TOP_OFFSET + 0] + 4) >> 3; dest[1] = (5 * dest[1] + 2 * p[1] + p[TOP_OFFSET + 1] + 4) >> 3; dest[2] = (5 * dest[2] + p[2] + 2 * p[TOP_OFFSET + 2] + 4) >> 3; dest[3] = (5 * dest[3] + p[3] + 2 * p[TOP_OFFSET + 3] + 4) >> 3; // Third row dest += hdim, p += hdim; dest[0] = (5 * dest[0] + 2 * p[0] + p[TOP_OFFSET + 0] + 4) >> 3; dest[1] = (5 * dest[1] + 2 * p[1] + p[TOP_OFFSET + 1] + 4) >> 3; dest[2] = (6 * dest[2] + p[2] + p[TOP_OFFSET + 2] + 4) >> 3; dest[3] = (6 * dest[3] + p[3] + p[TOP_OFFSET + 3] + 4) >> 3; // Fourth row (identical to third row) dest += hdim, p += hdim; dest[0] = (5 * dest[0] + 2 * p[0] + p[TOP_OFFSET + 0] + 4) >> 3; dest[1] = (5 * dest[1] + 2 * p[1] + p[TOP_OFFSET + 1] + 4) >> 3; dest[2] = (6 * dest[2] + p[2] + p[TOP_OFFSET + 2] + 4) >> 3; dest[3] = (6 * dest[3] + p[3] + p[TOP_OFFSET + 3] + 4) >> 3; return;}// weighNoLeft_Vert - Overlap with MV from vert. neighbor for upper left 4x4 pixelsstatic void weighNoLeft_Vert( PIXEL *dest, PIXEL const *p, int hdim ){ // First row dest[0] = (3 * dest[0] + p[TOP_OFFSET + 0] + 2) >> 2; dest[1] = (3 * dest[1] + p[TOP_OFFSET + 1] + 2) >> 2; dest[2] = (3 * dest[2] + p[TOP_OFFSET + 2] + 2) >> 2; dest[3] = (3 * dest[3] + p[TOP_OFFSET + 3] + 2) >> 2; // Second row dest += hdim, p += hdim; dest[0] = (7 * dest[0] + p[TOP_OFFSET + 0] + 4) >> 3; dest[1] = (7 * dest[1] + p[TOP_OFFSET + 1] + 4) >> 3; dest[2] = (3 * dest[2] + p[TOP_OFFSET + 2] + 2) >> 2; dest[3] = (3 * dest[3] + p[TOP_OFFSET + 3] + 2) >> 2; // Third row dest += hdim, p += hdim; dest[0] = (7 * dest[0] + p[TOP_OFFSET + 0] + 4) >> 3; dest[1] = (7 * dest[1] + p[TOP_OFFSET + 1] + 4) >> 3; dest[2] = (7 * dest[2] + p[TOP_OFFSET + 2] + 4) >> 3; dest[3] = (7 * dest[3] + p[TOP_OFFSET + 3] + 4) >> 3; // Fourth row (identical to third row) dest += hdim, p += hdim; dest[0] = (7 * dest[0] + p[TOP_OFFSET + 0] + 4) >> 3; dest[1] = (7 * dest[1] + p[TOP_OFFSET + 1] + 4) >> 3; dest[2] = (7 * dest[2] + p[TOP_OFFSET + 2] + 4) >> 3; dest[3] = (7 * dest[3] + p[TOP_OFFSET + 3] + 4) >> 3; return;}// weighLeft - Overlap with MV from left neighbor for upper left 4x4 pixelsstatic void weighLeft( PIXEL *dest, PIXEL const *p, int hdim ){ // First row dest[0] = (3 * dest[0] + p[0] + 2) >> 2; dest[1] = (7 * dest[1] + p[1] + 4) >> 3; dest[2] = (7 * dest[2] + p[2] + 4) >> 3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -