📄 umc_vc1_dec_mv_com.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) 2004-2007 Intel Corporation. All Rights Reserved.
//
//
// VC-1 (VC1) MV decoding
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_VC1_VIDEO_DECODER)
#include "umc_vc1_dec_seq.h"
#include "umc_vc1_dec_debug.h"
#include "umc_vc1_common_mvdiff_tbl.h"
void save_MV(VC1Context* pContext)
{
Ipp32s blk_num = 0;
VC1MB* pCurrMB = pContext->m_pCurrMB;
VC1SingletonMB* sMB = pContext->m_pSingleMB;
for (blk_num = 0; blk_num < 4;blk_num++)
{
if(pCurrMB->m_pBlocks[blk_num].blkType & VC1_BLK_INTRA)
{
continue;
}
pContext->savedMV[(sMB->widthMB * sMB->m_currMBYpos + sMB->m_currMBXpos)*4*2 +blk_num]
= pCurrMB->m_pBlocks[blk_num].mv[0][0];
pContext->savedMV[(sMB->widthMB * sMB->m_currMBYpos + sMB->m_currMBXpos)*4*2 +blk_num+4]
= pCurrMB->m_pBlocks[blk_num].mv[0][1];
}
}
void Derive4MV_Field(Ipp32u _MVcount,
Ipp16s* xMV, Ipp16s* yMV,
Ipp16s* xLuMV, Ipp16s* yLuMV)
{
switch(_MVcount)
{
case 0:
case 1:
{
VM_ASSERT(0);
return;
}
case 2:
{
*xMV = (xLuMV[0] + xLuMV[1]) / 2;
*yMV = (yLuMV[0] + yLuMV[1]) / 2;
return;
}
case 3:
{
*xMV = median3(xLuMV);
*yMV = median3(yLuMV);
return;
}
case 4:
{
*xMV = median4(xLuMV);
*yMV = median4(yLuMV);
return;
}
}
}
void GetPredictProgressiveMV(VC1Block *pA,VC1Block *pB,VC1Block *pC,
Ipp16s *pX, Ipp16s *pY,Ipp32s Back)
{
Ipp16s X=0, Y=0;
Ipp16s MV_px[] = {0,0,0};
Ipp16s MV_py[] = {0,0,0};
if (pA && (pA->blkType & VC1_BLK_INTER))
{
MV_px[0] = pA->mv[Back][0];
MV_py[0] = pA->mv[Back][1];
}
if (pB && (pB->blkType & VC1_BLK_INTER))
{
MV_px[1] = pB->mv[Back][0];
MV_py[1] = pB->mv[Back][1];
}
if (pC && (pC->blkType & VC1_BLK_INTER))
{
MV_px[2] = pC->mv[Back][0];
MV_py[2] = pC->mv[Back][1];
}
if (pA)
{
if (pB == NULL)
{
X = MV_px[0];
Y = MV_py[0];
}
else
{
X = median3(MV_px);
Y = median3(MV_py);
}
}
else if (pC)
{
X = MV_px[2];
Y = MV_py[2];
}
(*pX) = X;
(*pY) = Y;
}
void HybridMV(VC1Context* pContext,VC1Block *pA,VC1Block *pC, Ipp16s *pPredMVx,Ipp16s *pPredMVy, Ipp32s Back)
{
Ipp16s MV_px[] = {0,0};
Ipp16s MV_py[] = {0,0};
Ipp16s x, y;
Ipp16u sum;
Ipp32s eHybridPred;
if ((pA == NULL) || (pC == NULL) || (pContext->m_picLayerHeader->PTYPE == VC1_B_FRAME))
{
return;
}
x = (*pPredMVx);
y = (*pPredMVy);
if (pA && (pA->blkType & VC1_BLK_INTER))
{
MV_px[0] = pA->mv[Back][0];
MV_py[0] = pA->mv[Back][1];
}
if (pC && (pC->blkType & VC1_BLK_INTER))
{
MV_px[1] = pC->mv[Back][0];
MV_py[1] = pC->mv[Back][1];
}
sum = vc1_abs_16s(x-MV_px[0]) + vc1_abs_16s(y-MV_py[0]);
if (sum <= 32)
{
sum = vc1_abs_16s(x-MV_px[1]) + vc1_abs_16s(y-MV_py[1]);
}
if (sum <= 32)
{
return;
}
VC1_GET_BITS(1,eHybridPred );
if (eHybridPred)
{
x = MV_px[0];
y = MV_py[0];
}
else
{
x = MV_px[1];
y = MV_py[1];
}
(*pPredMVx)= x;
(*pPredMVy)= y;
}
void CalculateMV(Ipp16s x[],Ipp16s y[], Ipp16s *X, Ipp16s* Y)
{
Ipp16s temp_x[] = {0,0,0};
Ipp16s temp_y[] = {0,0,0};
Ipp16u n_intra = ((Ipp16u)(x[0])==VC1_MVINTRA) +
(((Ipp16u)(x[1])== VC1_MVINTRA)<<1) +
(((Ipp16u)(x[2])== VC1_MVINTRA)<<2) +
(((Ipp16u)(x[3])== VC1_MVINTRA)<<3);
//VM_Debug::GetInstance().vm_debug_frame(-1,VC1_BFRAMES,VM_STRING("history MVs(%d,%d) (%d,%d) (%d,%d) (%d,%d)\n"),x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3]);
switch(n_intra)
{
case 0x00: //all blocks are inter
*X = median4(x);
*Y = median4(y);
break;
case 0x01:
*X = median3(&x[1]);
*Y = median3(&y[1]);
break;
case 0x02:
temp_x[0] = x[0];
temp_x[1] = x[2];
temp_x[2] = x[3];
temp_y[0] = y[0];
temp_y[1] = y[2];
temp_y[2] = y[3];
*X = median3(temp_x);
*Y = median3(temp_y);
break;
case 0x04:
temp_x[0] = x[0];
temp_x[1] = x[1];
temp_x[2] = x[3];
temp_y[0] = y[0];
temp_y[1] = y[1];
temp_y[2] = y[3];
*X = median3(temp_x);
*Y = median3(temp_y);
break;
case 0x08:
*X = median3(x);
*Y = median3(y);
break;
case 0x03:
*X = (x[2]+ x[3])/2;
*Y = (y[2]+ y[3])/2;
break;
case 0x05:
*X = (x[1]+ x[3])/2;
*Y = (y[1]+ y[3])/2;
break;
case 0x06:
*X = (x[0]+ x[3])/2;
*Y = (y[0]+ y[3])/2;
break;
case 0x09:
*X = (x[1]+ x[2])/2;
*Y = (y[1]+ y[2])/2;
break;
case 0x0C:
*X = (x[0]+ x[1])/2;
*Y = (y[0]+ y[1])/2;
break;
case 0x0A:
*X = (x[0]+ x[2])/2;
*Y = (y[0]+ y[2])/2;
break;
default:
(*X)=VC1_MVINTRA;
(*Y)=VC1_MVINTRA;
break;
}
//VM_Debug::GetInstance().vm_debug_frame(-1,VC1_BFRAMES,VM_STRING("calculated history MVs(%d,%d)\n"),*X,*Y);
}
void CalculateMV_Interlace(Ipp16s x[],Ipp16s y[], Ipp16s x_bottom[],Ipp16s y_bottom[],Ipp16s *Xt, Ipp16s* Yt,Ipp16s *Xb, Ipp16s* Yb )
{
Ipp8s n_intra = ((Ipp16u)(x[0])==VC1_MVINTRA);
if (n_intra) // intra co-located MB
{
*Xt = 0;
*Yt = 0;
*Xb = 0;
*Yb = 0;
}
else
{
*Xt = x[0];
*Yt = y[0];
*Xb = x_bottom[0];
*Yb = y_bottom[0];
}
}
void CalculateMV_InterlaceField(VC1Context* pContext,Ipp16s x[],Ipp16s y[], Ipp16s *X, Ipp16s* Y)
{
Ipp8s n_intra = ((Ipp16u)(x[0])==VC1_MVINTRA);
Ipp32s count=0;
Ipp16s* xLuMV;
Ipp16s* yLuMV;
Ipp16s xLuMVT[VC1_NUM_OF_LUMA];
Ipp16s yLuMVT[VC1_NUM_OF_LUMA];
Ipp16s xLuMVB[VC1_NUM_OF_LUMA];
Ipp16s yLuMVB[VC1_NUM_OF_LUMA];
Ipp32u MVcount = 0;
Ipp32u MVBcount = 0;
Ipp32u MVTcount = 0;
Ipp8u* samePolarity = pContext->savedMVSamePolarity_Curr +
(pContext->m_seqLayerHeader->widthMB*pContext->m_pSingleMB->m_currMBYpos
+pContext->m_pSingleMB->m_currMBXpos)*4;
VC1MB* pMB = pContext->m_pCurrMB;
pContext->m_pCurrMB->m_pBlocks[0].fieldFlag[0] = pContext->m_picLayerHeader->BottomField;
if (n_intra)
{
*X = 0;
*Y = 0;
pContext->m_pCurrMB->m_pBlocks[0].mv_s_polarity[0] = 1;
pContext->m_pCurrMB->m_pBlocks[0].mv_s_polarity[1] = 1;
pContext->m_pCurrMB->m_pBlocks[0].fieldFlag[0] = pContext->m_picLayerHeader->BottomField;
}
else
{
for (count=0;count<4;count++)
{
if ((samePolarity[count])&&(pContext->m_picLayerHeader->BottomField)||
(!samePolarity[count])&&(!pContext->m_picLayerHeader->BottomField))
{
xLuMVB[MVBcount] = x[count];
yLuMVB[MVBcount] = y[count];
++MVBcount;
}
else
{
xLuMVT[MVTcount] = x[count];
yLuMVT[MVTcount] = y[count];
++MVTcount;
}
}
if (MVBcount == MVTcount)
{
MVcount = 2;
pContext->m_pCurrMB->m_pBlocks[0].mv_s_polarity[0] = 1;
pContext->m_pCurrMB->m_pBlocks[0].mv_s_polarity[1] = 1;
pContext->m_pCurrMB->m_pBlocks[0].fieldFlag[0] = pContext->m_pCurrMB->fieldFlag[0];
if (pContext->m_picLayerHeader->BottomField)
{
xLuMV = xLuMVB;
yLuMV = yLuMVB;
} else
{
xLuMV = xLuMVT;
yLuMV = yLuMVT;
}
} else if (MVBcount > MVTcount)
{
if (!pContext->m_picLayerHeader->BottomField)
{
pMB->m_pBlocks[0].mv_s_polarity[0] = 0;
pMB->m_pBlocks[0].mv_s_polarity[1] = 0;
}
else
{
pMB->m_pBlocks[0].mv_s_polarity[0] = 1;
pMB->m_pBlocks[0].mv_s_polarity[1] = 1;
}
MVcount = MVBcount;
xLuMV = xLuMVB;
yLuMV = yLuMVB;
pContext->m_pCurrMB->m_pBlocks[0].fieldFlag[0] = 1;
} else
{
if (pContext->m_picLayerHeader->BottomField)
{
pMB->m_pBlocks[0].mv_s_polarity[0] = 0;
pMB->m_pBlocks[0].mv_s_polarity[1] = 0;
}
else
{
pMB->m_pBlocks[0].mv_s_polarity[0] = 1;
pMB->m_pBlocks[0].mv_s_polarity[1] = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -