📄 umc_avs_dec_decompressor_mc.cpp
字号:
/*
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_VIDEO_DECODER)
#include "umc_avs_dec_decompressor.h"
#include "umc_avs_dec_pic.h"
namespace UMC
{
static
IppiSize AVSLumaBlockSize[4] =
{
{16, 16}, {16, 8}, {8, 16}, {8, 8}
};
void AVSDecompressor::CompensateMotionLumaPMacroBlock(void)
{
// set pointer to the block's beginning
m_lumaMCParams.pDst[0] = m_recCtx.m_pPlanes8u[0];
m_lumaMCParams.dstStep = m_recCtx.m_iPitch;
// set the initial block position
m_lumaMCParams.pointBlockPos.x = m_recCtx.MbX * 16;
m_lumaMCParams.pointBlockPos.y = m_recCtx.MbY * 16;
// select block size
m_lumaMCParams.sizeBlock = AVSLumaBlockSize[m_pMbInfo->divType];
switch (m_pMbInfo->divType)
{
case Div_16x16:
CompensateMotionLumaUniDir(0, PredForward);
break;
case Div_16x8:
CompensateMotionLumaUniDir(0, PredForward);
m_lumaMCParams.pointBlockPos.y += 8;
m_lumaMCParams.pDst[0] += m_lumaMCParams.dstStep * 8;
CompensateMotionLumaUniDir(2, PredForward);
break;
case Div_8x16:
CompensateMotionLumaUniDir(0, PredForward);
m_lumaMCParams.pointBlockPos.x += 8;
m_lumaMCParams.pDst[0] += 8;
CompensateMotionLumaUniDir(1, PredForward);
break;
default:
CompensateMotionLumaUniDir(0, PredForward);
m_lumaMCParams.pointBlockPos.x += 8;
m_lumaMCParams.pDst[0] += 8;
CompensateMotionLumaUniDir(1, PredForward);
m_lumaMCParams.pointBlockPos.x -= 8;
m_lumaMCParams.pointBlockPos.y += 8;
m_lumaMCParams.pDst[0] += m_lumaMCParams.dstStep * 8 - 8;
CompensateMotionLumaUniDir(2, PredForward);
m_lumaMCParams.pointBlockPos.x += 8;
m_lumaMCParams.pDst[0] += 8;
CompensateMotionLumaUniDir(3, PredForward);
break;
}
} // void AVSDecompressor::CompensateMotionLumaPMacroBlock(void)
#define COMPENSATE_MOTION_LUMA(block_num) \
{ \
eAVSPredType predType; \
predType = (eAVSPredType) m_pMbInfo->predType[block_num]; \
if (PredBiDir == predType) \
{ \
CompensateMotionLumaBiDir(block_num); \
} \
else \
{ \
CompensateMotionLumaUniDir(block_num, predType); \
} \
}
void AVSDecompressor::CompensateMotionLumaBMacroBlock(void)
{
// set pointer to the block's beginning
m_lumaMCParams.pDst[0] = m_recCtx.m_pPlanes8u[0];
m_lumaMCParams.dstStep = m_recCtx.m_iPitch;
// set the initial block position
m_lumaMCParams.pointBlockPos.x = m_recCtx.MbX * 16;
m_lumaMCParams.pointBlockPos.y = m_recCtx.MbY * 16;
// select block size
m_lumaMCParams.sizeBlock = AVSLumaBlockSize[m_pMbInfo->divType];
switch (m_pMbInfo->divType)
{
case Div_16x16:
COMPENSATE_MOTION_LUMA(0)
break;
case Div_16x8:
COMPENSATE_MOTION_LUMA(0)
m_lumaMCParams.pointBlockPos.y += 8;
m_lumaMCParams.pDst[0] += m_lumaMCParams.dstStep * 8;
COMPENSATE_MOTION_LUMA(2)
break;
case Div_8x16:
COMPENSATE_MOTION_LUMA(0)
m_lumaMCParams.pointBlockPos.x += 8;
m_lumaMCParams.pDst[0] += 8;
COMPENSATE_MOTION_LUMA(1)
break;
default:
COMPENSATE_MOTION_LUMA(0)
m_lumaMCParams.pointBlockPos.x += 8;
m_lumaMCParams.pDst[0] += 8;
COMPENSATE_MOTION_LUMA(1)
m_lumaMCParams.pointBlockPos.x -= 8;
m_lumaMCParams.pointBlockPos.y += 8;
m_lumaMCParams.pDst[0] += m_lumaMCParams.dstStep * 8 - 8;
COMPENSATE_MOTION_LUMA(2)
m_lumaMCParams.pointBlockPos.x += 8;
m_lumaMCParams.pDst[0] += 8;
COMPENSATE_MOTION_LUMA(3)
break;
}
} // void AVSDecompressor::CompensateMotionLumaBMacroBlock(void)
void AVSDecompressor::CompensateMotionLumaUniDir(Ipp32s blockNum, eAVSPredType typePred)
{
Ipp32s refIdx;
// set the source
{
AVSPicture *pRef;
refIdx = m_pMbInfo->refIdx[typePred - 1][blockNum];
pRef = m_pRef[typePred - 1][refIdx];
m_lumaMCParams.pSrc[0] = pRef->m_pPlanes8u[0];
m_lumaMCParams.srcStep = pRef->m_iPitch;
}
// set the vector
m_lumaMCParams.pointVector = m_pMbInfo->mv[typePred - 1][blockNum];
// do compensation
ippiInterpolateLumaBlock_AVS_8u_P1R(&m_lumaMCParams);
// do weighting
if (m_pMbInfo->weighting_prediction)
{
Ipp32s luma_scale, luma_shift;
// get weighting parameters
luma_scale = m_recCtx.m_pSlcHeader->luma_scale[typePred - 1][refIdx];
luma_shift = m_recCtx.m_pSlcHeader->luma_shift[typePred - 1][refIdx];
ippiWeightPrediction_AVS_8u_C1R(m_lumaMCParams.pDst[0],
m_lumaMCParams.dstStep,
m_lumaMCParams.pDst[0],
m_lumaMCParams.dstStep,
luma_scale,
luma_shift,
m_lumaMCParams.sizeBlock);
}
} // void AVSDecompressor::CompensateMotionLumaUniDir(Ipp32s blockNum, eAVSPredType typePred)
void AVSDecompressor::CompensateMotionLumaBiDir(Ipp32s blockNum)
{
Ipp8u tempBlock[16 * 16 + 16];
Ipp8u *pFrw, *pBck;
Ipp32s stepFrw, stepBck;
//
// do forward motion compensation
//
// zero motion vector - simple reset pointers
if (0 == m_pMbInfo->mv[AVS_FORWARD][blockNum].scalar)
{
Ipp32s refIdx;
AVSPicture *pRef;
refIdx = m_pMbInfo->refIdx[AVS_FORWARD][blockNum];
pRef = m_pRef[AVS_FORWARD][refIdx];
pFrw = pRef->m_pPlanes8u[0];
stepFrw = pRef->m_iPitch;
// calculate offset to a corresponding place in the reference picture
pFrw += m_lumaMCParams.pDst[0] - m_pPlanes8u[0];
// do weighting
if (m_pMbInfo->weighting_prediction)
{
Ipp32s luma_scale, luma_shift;
// get weighting parameters
luma_scale = m_recCtx.m_pSlcHeader->luma_scale[AVS_FORWARD][refIdx];
luma_shift = m_recCtx.m_pSlcHeader->luma_shift[AVS_FORWARD][refIdx];
ippiWeightPrediction_AVS_8u_C1R(pFrw,
stepFrw,
m_lumaMCParams.pDst[0],
m_lumaMCParams.dstStep,
luma_scale,
luma_shift,
m_lumaMCParams.sizeBlock);
// set the pointer to the block
pFrw = m_lumaMCParams.pDst[0];
stepFrw = m_lumaMCParams.dstStep;
}
}
// doing honest compensation
else
{
pFrw = m_lumaMCParams.pDst[0];
stepFrw = m_lumaMCParams.dstStep;
CompensateMotionLumaUniDir(blockNum, PredForward);
}
//
// do backward motion compensation
//
// zero motion vector - simple reset pointers
if (0 == m_pMbInfo->mv[AVS_BACKWARD][blockNum].scalar)
{
Ipp32s refIdx;
AVSPicture *pRef;
refIdx = m_pMbInfo->refIdx[AVS_BACKWARD][blockNum];
pRef = m_pRef[AVS_BACKWARD][refIdx];
pBck = pRef->m_pPlanes8u[0];
stepBck = pRef->m_iPitch;
// calculate offset to a corresponding place in the reference picture
pBck += m_lumaMCParams.pDst[0] - m_pPlanes8u[0];
// do weighting
if (m_pMbInfo->weighting_prediction)
{
Ipp32s luma_scale, luma_shift;
// get weighting parameters
luma_scale = m_recCtx.m_pSlcHeader->luma_scale[AVS_BACKWARD][refIdx];
luma_shift = m_recCtx.m_pSlcHeader->luma_shift[AVS_BACKWARD][refIdx];
ippiWeightPrediction_AVS_8u_C1R(pBck,
stepBck,
align_pointer<Ipp8u *> (tempBlock, 16),
16,
luma_scale,
luma_shift,
m_lumaMCParams.sizeBlock);
// set the pointer to the block
pBck = align_pointer<Ipp8u *> (tempBlock, 16);
stepBck = 16;
}
}
// doing honest compensation
else
{
Ipp8u *pDstPrev;
Ipp32s stepPrev;
// change the destination pointer
pDstPrev = m_lumaMCParams.pDst[0];
stepPrev = m_lumaMCParams.dstStep;
m_lumaMCParams.pDst[0] = align_pointer<Ipp8u *> (tempBlock, 16);
m_lumaMCParams.dstStep = 16;
pBck = m_lumaMCParams.pDst[0];
stepBck = m_lumaMCParams.dstStep;
CompensateMotionLumaUniDir(blockNum, PredBackward);
// restore the destination pointer
m_lumaMCParams.pDst[0] = pDstPrev;
m_lumaMCParams.dstStep = stepPrev;
}
// get average from two directions
ippiInterpolateBlock_H264_8u_P3P1R(pFrw,
pBck,
m_lumaMCParams.pDst[0],
m_lumaMCParams.sizeBlock.width,
m_lumaMCParams.sizeBlock.height,
stepFrw,
stepBck,
m_lumaMCParams.dstStep);
} // void AVSDecompressor::CompensateMotionLumaBiDir(Ipp32s blockNum)
static
IppiSize AVSChromaBlockSize[2][4] =
{
// 4:2:0 block sizes
{
{8, 8}, {8, 4}, {4, 8}, {4, 4}
},
// 4:2:2 block sizes
{
{8, 16}, {8, 8}, {4, 16}, {4, 8}
}
};
void AVSDecompressor::CompensateMotionChromaPMacroBlock(void)
{
Ipp32s blockHeight;
// set pointer to the block's beginning
m_chromaMCParams.pDst[0] = m_recCtx.m_pPlanes8u[1];
m_chromaMCParams.pDst[1] = m_recCtx.m_pPlanes8u[2];
m_chromaMCParams.dstStep = m_recCtx.m_iPitch;
// set the initial block position
m_chromaMCParams.pointBlockPos.x = m_recCtx.MbX * 8;
m_chromaMCParams.pointBlockPos.y = m_recCtx.MbY * 8;
// select block size
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -