mcomp.c
来自「symbian 下的helix player源代码」· C语言 代码 · 共 1,603 行 · 第 1/5 页
C
1,603 行
source = prev.pix;
for (dest = pixel.pix; dest < pixel.pix + 8; dest++) {
*dest = *(source++);
}
pixel.pix += pic->cr.hoffset;
prev.pix += pic->cr.hoffset;
}
}
}
return (status);
}
// MotionComp263 - perform half-pixel motion compensation for H.263
extern 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 luma
extern 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-frame
extern 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];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?