📄 mcomp.c
字号:
}// 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 + -