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 + -
显示快捷键?