mcomp.c
来自「symbian 下的helix player源代码」· C语言 代码 · 共 1,603 行 · 第 1/5 页
C
1,603 行
}
} 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 );
}
// PredBdist - Form prediction for subsampled error computation
extern 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 component
static 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 components
static 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 block
void 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 picture
static 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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?