📄 mcomp.c
字号:
// PredBdist - Form prediction for subsampled error computationextern void PredBdist( 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 );}// chromaMVComp - derive motion component for chroma from luma motion componentstatic int chromaMVComp( int mvLuma ){ int mvChroma, fraction; mvChroma = 2 * (mvLuma >> 2); // Truncate fractional part fraction = mvLuma & 0x3; // Two fractional bits if (fraction != 0) { ++mvChroma; // Round towards half-pixel } return( mvChroma );}// chromaMvComp4V - derive motion component for chroma from 4 luma motion componentsstatic int chromaMvComp4V( S8 mvLuma[4] ){ int sum, mvChroma, fraction; sum = mvLuma[0] + mvLuma[1] + mvLuma[2] + mvLuma[3]; mvChroma = 2 * (sum >> 4); // Truncate fractional part fraction = sum & 0xf; // Four fractional bits if (fraction >= 14) { mvChroma += 2; // Round up to next integer value } else if (fraction >= 3) { ++mvChroma; // Round towards half-pixel } // else round down to integer pixel return( mvChroma );}// mc - Perform motion compensation for a hSize x vSize blockvoid mc( int hSize, int vSize, PIXEL *in, PIXEL *out, int hdim, int mvX, int mvY // Motion vector ){ int intX, intY, fracX, fracY; #ifdef VVPROFILER S32 nVvProfNb = 2; if(!pVvProf[nVvProfNb]) pVvProf[nVvProfNb] = newCVvDebugTimer();//memory leak on destruction pVvProfCount[nVvProfNb]++; StartTime(pVvProf[nVvProfNb]);#endif intX = mvX >> 1; // Integer part of motion vector intY = mvY >> 1; fracX = mvX & 0x1; // Fractional part of motion vector fracY = mvY & 0x1; in += intX + intY * hdim; if (hSize != 16 && hSize != 8 && hSize != 4) { H261ErrMsg("mc -- hSize not supported"); exit(0); } if (fracY == 0) { if (fracX == 0) { // No interpolation if (hSize == 8) { mc8pelsNoInterpol( in, out, hdim, vSize ); } else if (hSize == 16) { mc16pelsNoInterpol( in, out, hdim, vSize ); } else { mc4pelsNoInterpol( in, out, hdim, vSize ); } } else { // Horizontal interpolation if (hSize == 8) { mc8pelsHorInterpol( in, out, hdim, vSize ); } else if (hSize == 16) { mc16pelsHorInterpol( in, out, hdim, vSize ); } else { mc4pelsHorInterpol( in, out, hdim, vSize ); } } } else if (fracX == 0) { // Vertical interpolation if (hSize == 8) { mc8pelsVertInterpol( in, out, hdim, vSize ); } else if (hSize == 16) { mc16pelsVertInterpol( in, out, hdim, vSize ); } else { mc4pelsVertInterpol( in, out, hdim, vSize ); } } else { // Bilinear interpolation if (hSize == 8) { mc8pels2DInterpol( in, out, hdim, vSize ); } else if (hSize == 16) { mc16pels2DInterpol( in, out, hdim, vSize ); } else { mc4pels2DInterpol( in, out, hdim, vSize ); } }#ifdef VVPROFILER StopAndAccuTime(pVvProf[nVvProfNb]);#endif return;}// Limit x to interval [low,high]#define LIMIT( low, x, high ) max( low, min( x, high ))// limitMC - Perform motion compensation; use edge pixels when referring to// pixels outside picturestatic void limitMC( int hSize, int vSize, PIXEL const *in, PIXEL *out, int hdim, int mvX, int mvY, // Motion vector int minX, int maxX, int minY, int maxY // Limits for hor/vert indices ){#define MAX_HSIZE (16) int intX, intY, fracX, fracY, outsideTop, outsideBot, repeatTop, repeatBot, x, y; static int mapX[MAX_HSIZE + 1]; PIXEL *outSave, *outBegin; union { // Copy words to speed up routine PIXEL *pix; U32 *word; } pIn, pOut; if (hSize & 0x3) { H261ErrMsg("limitMC -- hSize must be multiple of 4"); exit(0); } if (hSize > MAX_HSIZE) { H261ErrMsg("limitMC -- hSize too large"); exit(0); } intX = mvX >> 1; // Integer part of motion vector intY = mvY >> 1; fracX = mvX & 0x1; // Fractional part of motion vector fracY = mvY & 0x1; // Create horizontal mapping vector for (x = 0; x <= hSize; ++x) { mapX[x] = LIMIT( minX, x + intX, maxX ); } //repeatTop = max( 0, minY - intY); // Lines on top that are outside //repeatBot = max( 0, vSize - 1 + intY + fracY - maxY); // Lines at bottom that are outside outsideTop = max( 0, minY - intY); // Lines on top that are outside outsideBot = max( 0, vSize - 1 + intY + fracY - maxY); // Lines at bottom that are outside // Don't produce more lines than the blocksize (used to be a nasty bug hidden here) repeatTop = min( outsideTop, vSize ); if (outsideBot < vSize) { repeatBot = outsideBot; in += (intY + outsideTop) * hdim; // Apply vert motion comp. (hor MC thru mapping) } else { // Whole block is "outside" bottom of picture repeatBot = vSize; in += (vSize - 1) * hdim; // Point to last line of picture } // Output pointers outSave = out; // Upper left corner of output block out += repeatTop * hdim; // "Repeated" lines will be filled in later outBegin = out; // Save address for first valid output line if (fracY == 0) { // Ensure that at least one output line gets written if (repeatTop == vSize) { --repeatTop; out -= hdim; outBegin = out; } else if (repeatBot == vSize) { --repeatBot; } if (fracX == 0) { // No interpolation for (y = repeatTop; y < vSize - repeatBot; ++y) { for (x = 0; x < hSize; x += 4) { out[x+0] = in[ mapX[x+0] ]; out[x+1] = in[ mapX[x+1] ]; out[x+2] = in[ mapX[x+2] ]; out[x+3] = in[ mapX[x+3] ]; } in += hdim; out += hdim; } } else { // Horizontal interpolation for (y = repeatTop; y < vSize - repeatBot; ++y) { for (x = 0; x < hSize; x += 4) { out[x+0] = (in[mapX[x+0]] + in[mapX[x+1]] + 1) >> 1; out[x+1] = (in[mapX[x+1]] + in[mapX[x+2]] + 1) >> 1; out[x+2] = (in[mapX[x+2]] + in[mapX[x+3]] + 1) >> 1; out[x+3] = (in[mapX[x+3]] + in[mapX[x+4]] + 1) >> 1; } in += hdim; out += hdim; } } } else if (fracX == 0) { // Vertical interpolation if (repeatTop > 0) { // Produce line to repeat outBegin = out - hdim; for (x = 0; x < hSize; ++x) { outBegin[x] = in[ mapX[x] ]; } } for (y = repeatTop; y < vSize - repeatBot; ++y) { for (x = 0; x < hSize; x += 4) { out[x+0] = (in[mapX[x+0]] + in[mapX[x+0] + hdim] + 1) >> 1; out[x+1] = (in[mapX[x+1]] + in[mapX[x+1] + hdim] + 1) >> 1; out[x+2] = (in[mapX[x+2]] + in[mapX[x+2] + hdim] + 1) >> 1; out[x+3] = (in[mapX[x+3]] + in[mapX[x+3] + hdim] + 1) >> 1; } in += hdim; out += hdim; } if (repeatBot > 0) { // Produce line to repeat for (x = 0; x < hSize; ++x) { out[x] = in[ mapX[x] ]; } out += hdim; } } else { // Bilinear interpolation if (repeatTop > 0) { // Produce line to repeat outBegin = out - hdim; for (x = 0; x < hSize; ++x) { outBegin[x] = (in[mapX[x]] + in[mapX[x+1]] + 1) >> 1; } } for (y = repeatTop; y < vSize - repeatBot; ++y) { for (x = 0; x < hSize; x += 4) { out[x+0] = (in[mapX[x+0]] + in[mapX[x+0] + hdim] + in[mapX[x+1]] + in[mapX[x+1] + hdim] + 2) >> 2; out[x+1] = (in[mapX[x+1]] + in[mapX[x+1] + hdim] + in[mapX[x+2]] + in[mapX[x+2] + hdim] + 2) >> 2; out[x+2] = (in[mapX[x+2]] + in[mapX[x+2] + hdim] + in[mapX[x+3]] + in[mapX[x+3] + hdim] + 2) >> 2; out[x+3] = (in[mapX[x+3]] + in[mapX[x+3] + hdim] + in[mapX[x+4]] + in[mapX[x+4] + hdim] + 2) >> 2; } in += hdim; out += hdim; } if (repeatBot > 0) { // Produce line to repeat for (x = 0; x < hSize; ++x) { out[x] = (in[mapX[x]] + in[mapX[x+1]] + 1) >> 1; } out += hdim; } } if (fracY == 1) { --repeatTop; // Already did one line --repeatBot; } // Repeat first line at top pIn.pix = outBegin; pOut.pix = outSave; for (y = 0; y < repeatTop; ++y) { for (x = 0; x < (hSize >> 2); ++x) { *(pOut.word + x) = *(pIn.word + x); } pOut.pix += hdim; } // Repeat last line at the bottom pIn.pix = out - hdim; pOut.pix = out; for (y = 0; y < repeatBot; ++y) { for (x = 0; x < (hSize >> 2); ++x) { *(pOut.word + x) = *(pIn.word + x); } pOut.pix += hdim; } return;}// mvDiff - Return YES if motion vector for adjacent block is different, otherwise NO// Return NO if adjacent block is INTRA (unless PBframe)static int mvDiff( int mvX, int mvY, // motion vector MACROBLOCK_DESCR const *borderMB, // adjacent macroblock int subBlk, // adjacent subblock (needed if borderMB has 4 motion vectors) int PBframe, // If PBframe: do overlap also with INTRA neighbor int border[2] // return motion vector components for adjacent block ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -