?? mc.cpp
字號:
CoordI x, CoordI y,
const CMBMode *pmbmd,
const CMotionVector *pmv,
CRct *prctMVLimit
)
{
CVOPU8YUVBA *pvopcRef;
Int topRef, botRef;
if (type == BACKWARD) {
pvopcRef = m_pvopcRefQ1;
topRef = (Int)pmbmd->m_bBackwardTop;
botRef = (Int)pmbmd->m_bBackwardBottom;
} else {
pvopcRef = m_pvopcRefQ0;
topRef = (Int)pmbmd->m_bForwardTop;
botRef = (Int)pmbmd->m_bForwardBottom;
}
if (pmbmd->m_bFieldMV) {
const CMotionVector *pmvTop = pmv + 1 + topRef;
const CMotionVector *pmvBot = pmv + 3 + botRef;
assert((topRef & ~1) == 0); assert((botRef & ~1) == 0);
CoordI iMVX, iMVY;
if (m_volmd.bQuarterSample) {
iMVX = 4*x + pmvTop->m_vctTrueHalfPel.x;
iMVY = 4*y + pmvTop->m_vctTrueHalfPel.y;
// limitMVRangeToExtendedBBQuarterPel(iMVX, iMVY, prctMVLimit, MB_SIZE);
// Luma top field
motionCompQuarterSample((PixelC *)pvopcPred->pixelsY(),
pvopcRef->pixelsY() + topRef * m_iFrameWidthY, 0,
iMVX, iMVY, m_vopmd.iRoundingControl, prctMVLimit);
iMVX = 2*x + pmvTop->iMVX;
iMVY = 2*y + pmvTop->iMVY;
// limitMVRangeToExtendedBBHalfPel(iMVX, iMVY, prctMVLimit, MB_SIZE);
}
else {
iMVX = 2*x + pmvTop->m_vctTrueHalfPel.x;
iMVY = 2*y + pmvTop->m_vctTrueHalfPel.y;
// limitMVRangeToExtendedBBHalfPel(iMVX, iMVY, prctMVLimit, MB_SIZE);
motionCompYField((PixelC *)pvopcPred->pixelsY(), // Luma top field
pvopcRef->pixelsY() + topRef * m_iFrameWidthY, iMVX, iMVY, prctMVLimit);
}
iMVX -= 2*x; iMVY -= 2*y;
motionCompFieldUV((PixelC *)pvopcPred->pixelsU(), // Chroma top field
(PixelC *)pvopcPred->pixelsV(), pvopcRef, x, y,
(iMVX & 3) ? ((iMVX >> 1) | 1) : (iMVX >> 1),
(iMVY & 6) ? ((iMVY >> 1) | 2) : (iMVY >> 1), topRef,
prctMVLimit);
if (m_volmd.bQuarterSample) {
iMVX = 4*x + pmvBot->m_vctTrueHalfPel.x;
iMVY = 4*y + pmvBot->m_vctTrueHalfPel.y;
// limitMVRangeToExtendedBBQuarterPel(iMVX, iMVY, prctMVLimit, MB_SIZE);
// Luma bottom field
motionCompQuarterSample((PixelC *)(pvopcPred->pixelsY()) + MB_SIZE,
pvopcRef->pixelsY() + botRef * m_iFrameWidthY, 0,
iMVX, iMVY, m_vopmd.iRoundingControl, prctMVLimit);
iMVX = 2*x + pmvBot->iMVX;
iMVY = 2*y + pmvBot->iMVY;
// limitMVRangeToExtendedBBHalfPel(iMVX, iMVY, prctMVLimit, MB_SIZE);
}
else {
iMVX = 2*x + pmvBot->m_vctTrueHalfPel.x;
iMVY = 2*y + pmvBot->m_vctTrueHalfPel.y;
// limitMVRangeToExtendedBBHalfPel(iMVX, iMVY, prctMVLimit, MB_SIZE);
motionCompYField((PixelC *)(pvopcPred->pixelsY()) + MB_SIZE, // Luma bottom field
pvopcRef->pixelsY() + botRef * m_iFrameWidthY, iMVX, iMVY,
prctMVLimit);
}
iMVX -= 2*x; iMVY -= 2*y;
motionCompFieldUV((PixelC *)(pvopcPred->pixelsU()) + BLOCK_SIZE, // Chroma bottom field
(PixelC *)(pvopcPred->pixelsV()) + BLOCK_SIZE, pvopcRef, x, y,
(iMVX & 3) ? ((iMVX >> 1) | 1) : (iMVX >> 1),
(iMVY & 6) ? ((iMVY >> 1) | 2) : (iMVY >> 1), botRef, prctMVLimit);
} else { // no longer -> // rounding control is messed up here
if (m_volmd.bQuarterSample)
motionCompQuarterSample((PixelC *)pvopcPred->pixelsY(), pvopcRef->pixelsY(), MB_SIZE,
x * 4 + pmv->trueMVHalfPel().x, y * 4 + pmv->trueMVHalfPel().y,
m_vopmd.iRoundingControl, prctMVLimit);
else
motionComp((PixelC *)pvopcPred->pixelsY(), pvopcRef->pixelsY(), MB_SIZE,
x * 2 + pmv->trueMVHalfPel().x, y * 2 + pmv->trueMVHalfPel().y, m_vopmd.iRoundingControl, prctMVLimit);
// changed by mwi 980806
// motionCompUV((PixelC *)pvopcPred->pixelsU(), (PixelC *)pvopcPred->pixelsV(), pvopcRef, x, y,
// (pmv->m_vctTrueHalfPel.x & 3) ? ((pmv->m_vctTrueHalfPel.x >> 1) | 1) :
// (pmv->m_vctTrueHalfPel.x >> 1),
// (pmv->m_vctTrueHalfPel.y & 3) ? ((pmv->m_vctTrueHalfPel.y >> 1) | 1) :
// (pmv->m_vctTrueHalfPel.y >> 1), m_vopmd.iRoundingControl, prctMVLimit);
// GMC
if (m_volmd.bQuarterSample)
// ~GMC
motionCompUV((PixelC *)pvopcPred->pixelsU(), (PixelC *)pvopcPred->pixelsV(), pvopcRef, x, y,
(pmv->iMVX & 3) ? ((pmv->iMVX >> 1) | 1) :
(pmv->iMVX >> 1),
(pmv->iMVY & 3) ? ((pmv->iMVY >> 1) | 1) :
(pmv->iMVY >> 1), m_vopmd.iRoundingControl, prctMVLimit);
// GMC
else
motionCompUV((PixelC *)pvopcPred->pixelsU(), (PixelC *)pvopcPred->pixelsV(), pvopcRef, x, y,
(pmv->m_vctTrueHalfPel.x & 3) ? ((pmv->m_vctTrueHalfPel.x >> 1) | 1) :
(pmv->m_vctTrueHalfPel.x >> 1),
(pmv->m_vctTrueHalfPel.y & 3) ? ((pmv->m_vctTrueHalfPel.y >> 1) | 1) :
(pmv->m_vctTrueHalfPel.y >> 1), m_vopmd.iRoundingControl, prctMVLimit);
// changed by Y.Suzuki 99/02/03
// ~GMC
// ~changed by mwi 980806
}
}
Void CVideoObject::motionCompYField (
PixelC* ppxlcPred, // can be either Y or A
const PixelC* ppxlcRefLeftTop, // point to left-top of the frame
CoordI xRef, CoordI yRef, // current coordinate system
CRct *prctMVLimit // added by Y.Suzuki for the extended bounding box support
)
{
CoordI ix, iy;
limitMVRangeToExtendedBBHalfPel(xRef, yRef, prctMVLimit, MB_SIZE); // added by Y.Suzuki for the extended bounding box support
const PixelC* ppxlcRef = ppxlcRefLeftTop +
(((yRef >> 1) & ~1) + EXPANDY_REF_FRAME) * m_iFrameWidthY + (xRef >> 1) + EXPANDY_REF_FRAME;
Int iRound = 1 - m_vopmd.iRoundingControl;
Int iFieldStep = 2 * m_iFrameWidthY;
if (!(yRef & 2)) {
if (!(xRef & 1)) { //!bXSubPxl && !bYSubPxl
for (iy = 0; iy < MB_SIZE; iy+=2) {
memcpy (ppxlcPred, ppxlcRef, MB_SIZE*sizeof(PixelC));
ppxlcRef += iFieldStep;
ppxlcPred += MB_SIZE*2;
}
}
else { //bXSubPxl && !bYSubPxl
for (iy = 0; iy < MB_SIZE; iy+=2){
for (ix = 0; ix < MB_SIZE; ix++)
ppxlcPred [ix] = (ppxlcRef [ix] + ppxlcRef [ix + 1] + iRound) >> 1;
ppxlcRef += iFieldStep;
ppxlcPred += MB_SIZE*2;
}
}
}
else {
const PixelC* ppxlcRefBot;
if (!(xRef & 1)) { //!bXSubPxl&& bYSubPxl
for (iy = 0; iy < MB_SIZE; iy+=2) {
ppxlcRefBot = ppxlcRef + iFieldStep; //UPln -> pixels (xInt,yInt+1);
for (ix = 0; ix < MB_SIZE; ix++)
ppxlcPred [ix] = (ppxlcRef [ix] + ppxlcRefBot [ix] + iRound) >> 1;
ppxlcRef = ppxlcRefBot;
ppxlcPred += MB_SIZE*2;
}
}
else { // bXSubPxl && bYSubPxl
iRound++;
for (iy = 0; iy < MB_SIZE; iy+=2) {
ppxlcRefBot = ppxlcRef + iFieldStep; //UPln -> pixels (xInt,yInt+1);
for (ix = 0; ix < MB_SIZE; ix++){
ppxlcPred [ix] = (ppxlcRef [ix + 1] + ppxlcRef [ix] +
ppxlcRefBot [ix + 1] + ppxlcRefBot [ix] + iRound) >> 2;
}
ppxlcRef = ppxlcRefBot;
ppxlcPred += MB_SIZE*2;
}
}
}
}
Void CVideoObject::motionCompFieldUV ( PixelC* ppxlcPredMBU, PixelC* ppxlcPredMBV,
const CVOPU8YUVBA* pvopcRef,
CoordI x, CoordI y,
CoordI xRefUV, CoordI yRefUV,Int iRefFieldSelect,
CRct* prctMVLimit // added by Y.Suzuki for the extended bounding box support
)
{
UInt ix, iy;
// added by Y.Suzuki for the extended bounding box support
CoordI iTmpX = x + xRefUV;
CoordI iTmpY = y + yRefUV;
limitMVRangeToExtendedBBFullPel(iTmpX, iTmpY, prctMVLimit, MB_SIZE);
xRefUV = iTmpX - x;
yRefUV = iTmpY - y;
// ~extended bounding box support
// delete by Hyundai for Microsoft and MoMusys alignment
//Int iPxLoc = ((((y + yRefUV) >> 1) & ~1) + EXPANDUV_REF_FRAME) * m_iFrameWidthUV + ((x + xRefUV) >> 1) + EXPANDUV_REF_FRAME;
// insert by Hyundai for Microsoft and MoMusys alignment
Int iPxLoc = (y/2 + ((yRefUV >> 1) & ~1) + EXPANDUV_REF_FRAME) * m_iFrameWidthUV + ((x + xRefUV) >> 1) + EXPANDUV_REF_FRAME;
const PixelC* ppxlcPrevU = pvopcRef->pixelsU () + iPxLoc + iRefFieldSelect*m_iFrameWidthUV;
const PixelC* ppxlcPrevV = pvopcRef->pixelsV () + iPxLoc + iRefFieldSelect*m_iFrameWidthUV;
Int iRound = 1 - m_vopmd.iRoundingControl;
Int iFieldStep = 2 * m_iFrameWidthUV;
if (!(yRefUV & 2)) {
if (!(xRefUV & 1)) { //!bXSubPxl && !bYSubPxl
for (iy = 0; iy < BLOCK_SIZE; iy+=2) {
memcpy (ppxlcPredMBU, ppxlcPrevU, BLOCK_SIZE*sizeof(PixelC));
memcpy (ppxlcPredMBV, ppxlcPrevV, BLOCK_SIZE*sizeof(PixelC));
ppxlcPrevU += iFieldStep;
ppxlcPrevV += iFieldStep;
ppxlcPredMBU += 2*BLOCK_SIZE;
ppxlcPredMBV += 2*BLOCK_SIZE;
}
}
else { //bXSubPxl && !bYSubPxl
for (iy = 0; iy < BLOCK_SIZE; iy+=2) {
for (ix = 0; ix < BLOCK_SIZE; ix++) {
ppxlcPredMBU [ix] = (ppxlcPrevU [ix + 1] + ppxlcPrevU [ix] + iRound) >> 1;
ppxlcPredMBV [ix] = (ppxlcPrevV [ix + 1] + ppxlcPrevV [ix] + iRound) >> 1;
}
ppxlcPrevU += iFieldStep;
ppxlcPrevV += iFieldStep;
ppxlcPredMBU += 2*BLOCK_SIZE;
ppxlcPredMBV += 2*BLOCK_SIZE;
}
}
}
else {
const PixelC* ppxlcPrevUBot;
const PixelC* ppxlcPrevVBot;
if (!(xRefUV & 1)) { //!bXSubPxl&& bYSubPxl
for (iy = 0; iy < BLOCK_SIZE; iy+=2) {
ppxlcPrevUBot = ppxlcPrevU + iFieldStep; //UPln -> pixels (xInt,yInt+1);
ppxlcPrevVBot = ppxlcPrevV + iFieldStep; //VPln -> pixels (xInt,yInt+1);
for (ix = 0; ix < BLOCK_SIZE; ix++) {
ppxlcPredMBU [ix] = (ppxlcPrevU [ix] + ppxlcPrevUBot [ix] + iRound) >> 1;
ppxlcPredMBV [ix] = (ppxlcPrevV [ix] + ppxlcPrevVBot [ix] + iRound) >> 1;
}
ppxlcPredMBU += 2*BLOCK_SIZE;
ppxlcPredMBV += 2*BLOCK_SIZE;
ppxlcPrevU = ppxlcPrevUBot;
ppxlcPrevV = ppxlcPrevVBot;
}
}
else { // bXSubPxl && bYSubPxl
iRound++;
for (iy = 0; iy < BLOCK_SIZE; iy+=2){
ppxlcPrevUBot = ppxlcPrevU + iFieldStep; //UPln -> pixels (xInt,yInt+1);
ppxlcPrevVBot = ppxlcPrevV + iFieldStep; //VPln -> pixels (xInt,yInt+1);
for (ix = 0; ix < BLOCK_SIZE; ix++){
ppxlcPredMBU [ix] = (ppxlcPrevU [ix + 1] + ppxlcPrevU [ix] +
ppxlcPrevUBot [ix + 1] + ppxlcPrevUBot [ix] + iRound) >> 2;
ppxlcPredMBV [ix] = (ppxlcPrevV [ix + 1] + ppxlcPrevV [ix] +
ppxlcPrevVBot [ix + 1] + ppxlcPrevVBot [ix] + iRound) >> 2;
}
ppxlcPredMBU += 2*BLOCK_SIZE;
ppxlcPredMBV += 2*BLOCK_SIZE;
ppxlcPrevU = ppxlcPrevUBot;
ppxlcPrevV = ppxlcPrevVBot;
}
}
}
}
// #endif // INTERLACE
Void CVideoObject::motionCompUV (
PixelC* ppxlcPredMBU, PixelC* ppxlcPredMBV,
const CVOPU8YUVBA* pvopcRef,
CoordI x, CoordI y,
CoordI xRefUV, CoordI yRefUV,
Int iRoundingControl,
CRct *prctMVLimit
)
{
Int ix, iy;
CoordI iTmpX = x + xRefUV;
CoordI iTmpY = y + yRefUV;
// RRV modification
limitMVRangeToExtendedBBFullPel(iTmpX, iTmpY, prctMVLimit,
(MB_SIZE *m_iRRVScale));
// limitMVRangeToExtendedBBFullPel (iTmpX,iTmpY,prctMVLimit,MB_SIZE);
// ~RRV
xRefUV = iTmpX - x;
yRefUV = iTmpY - y;
Int iPxLoc = (((y + yRefUV) >> 1) + EXPANDUV_REF_FRAME) * m_iFrameWidthUV + ((x + xRefUV) >> 1) + EXPANDUV_REF_FRAME;
const PixelC* ppxlcPrevU = pvopcRef->pixelsU () + iPxLoc;
const PixelC* ppxlcPrevV = pvopcRef->pixelsV () + iPxLoc;
if (!(yRefUV & 1)) {
if (!(xRefUV & 1)) { //!bXSubPxl && !bYSubPxl
// RRV modification
for (iy = 0; iy < (BLOCK_SIZE *m_iRRVScale); iy++) {
memcpy(ppxlcPredMBU, ppxlcPrevU,
(BLOCK_SIZE *m_iRRVScale) *sizeof(PixelC));
memcpy(ppxlcPredMBV, ppxlcPrevV,
(BLOCK_SIZE *m_iRRVScale) *sizeof(PixelC));
ppxlcPrevU += m_iFrameWidthUV;
ppxlcPrevV += m_iFrameWidthUV;
ppxlcPredMBU += (BLOCK_SIZE *m_iRRVScale);
ppxlcPredMBV += (BLOCK_SIZE *m_iRRVScale);
}
// for (iy = 0; iy < BLOCK_SIZE; iy++) {
// memcp
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -