📄 umc_me.cpp
字号:
GetCost<mt,pix,SAD>(pSrc,srcStep,pRef,refStep, cost,mc_type);
break;
case SADT:
GetCost<mt,pix,SADT>(pSrc,srcStep,pRef,refStep, cost,mc_type);
break;
default:
assert(false);
}
}
template<MeMbPart mt, MeInPixType pix, MeCostEnum cst> inline void MeBase::GetCost(const Ipp8u* /*pSrc*/,Ipp32s /*srcStep*/,const Ipp8u* /*pRef*/,Ipp32s /*refStep*/,MeCost * /*cost*/,Ipp32s /*mcType*/)
{
printf("Illegal call of MeBase::GetCost %d %d %d\n",mt, pix, cst);
assert(0);
}
//SAD:
template<> inline void MeBase::GetCost<Mb16x16,QuadPixIn,SAD>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{ippiSAD4x4_8u32s(pSrc, srcStep, pRef, refStep, &(cost->sum), 0);}
template<> inline void MeBase::GetCost<Mb4x8x8,QuadPixIn,SAD>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{ippiSAD4x4Blocks2x2_8u16u(pSrc, srcStep, pRef, refStep, &(cost->sum8x8[0]), 0);}
template<> inline void MeBase::GetCost<Mb16x16,IntegerPixIn,SAD>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{ippiSAD16x16_8u32s(pSrc, srcStep, pRef, refStep, &(cost->sum), 0);}
template<> inline void MeBase::GetCost<Mb4x8x8,IntegerPixIn,SAD>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{ippiSAD16x16Blocks8x8_8u16u(pSrc, srcStep, pRef, refStep, &(cost->sum8x8[0]), 0);}
template<> inline void MeBase::GetCost<Mb8x8,IntegerPixIn,SAD>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{ippiSAD8x8_8u32s(pSrc, srcStep, pRef, refStep, &(cost->sum), 0);}
template<> inline void MeBase::GetCost<Mb16x16,HalfPixIn,SAD>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s mcType)
{ippiSAD16x16_8u32s(pSrc, srcStep, pRef, refStep, &(cost->sum), mcType);}
template<> inline void MeBase::GetCost<Mb16x16,QuarterPixIn,SAD>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{ippiSAD16x16_8u32s(pSrc, srcStep, pRef, refStep, &(cost->sum), 0);}
//SADT:
template<> inline void MeBase::GetCost<Mb16x16,QuadPixIn,SADT>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{cost->sum = SATD<Ipp8u>((Ipp8u*)pSrc, srcStep,(Ipp8u*) pRef, refStep,BS_2x2);}
template<> inline void MeBase::GetCost<Mb4x8x8,QuadPixIn,SADT>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{cost->sum = SATD<Ipp8u>((Ipp8u*)pSrc, srcStep,(Ipp8u*) pRef, refStep,BS_2x2);}
template<> inline void MeBase::GetCost<Mb16x16,IntegerPixIn,SADT>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{cost->sum = SATD<Ipp8u>((Ipp8u*)pSrc, srcStep, (Ipp8u*)pRef, refStep,BS_8x8);}
template<> inline void MeBase::GetCost<Mb4x8x8,IntegerPixIn,SADT>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{cost->sum = SATD<Ipp8u>((Ipp8u*)pSrc, srcStep, (Ipp8u*)pRef, refStep,BS_8x8);}
template<> inline void MeBase::GetCost<Mb8x8,IntegerPixIn,SADT>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{cost->sum = SATD<Ipp8u>((Ipp8u*)pSrc, srcStep, (Ipp8u*)pRef, refStep,BS_8x8);}
template<> inline void MeBase::GetCost<Mb16x16,HalfPixIn,SADT>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s mcType)
{cost->sum = SATD<Ipp8u>((Ipp8u*)pSrc, srcStep, (Ipp8u*)pRef, refStep,BS_8x8);}
template<> inline void MeBase::GetCost<Mb16x16,QuarterPixIn,SADT>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{cost->sum = SATD<Ipp8u>((Ipp8u*)pSrc, srcStep, (Ipp8u*)pRef, refStep,BS_8x8);}
template<> inline void MeBase::GetCost<Mb16x16,IntegerPixIn,MAXAD>(const Ipp8u* pSrc, Ipp32s srcStep, const Ipp8u* pRef, Ipp32s refStep, MeCost *cost, Ipp32s /*mcType*/)
{
Ipp32s i;
Ipp8u m_diff[256];
IppiSize roiSize;
roiSize.width = 16;
roiSize.height = 16;
ippiAbsDiff_8u_C1R(pSrc,srcStep,pRef, refStep,m_diff,16,roiSize);
cost->sum = m_diff[0];
for(i = 1; i < 256; i++) if(cost->sum < m_diff[i]) cost->sum = m_diff[i];
}
//skipped:
bool MeBase::EstimateSkipped()
{
const Ipp8u *pSrc, *pRef;
MeCost cost;
pSrc=m_pSrcFrameY+16*m_CurMB.y*m_SrcStep+16*m_CurMB.x;
pRef = m_pRefFrameY + 16*(m_CurMB.x + m_CurMB.y*m_RefStep);
Interpolate(pRef,m_RefStep,m_16x16buf,16, m_CurPrediction);
switch(m_MePar->SkippedMetrics)
{
case maxad:
GetCost<Mb16x16,IntegerPixIn,MAXAD>(pSrc,m_SrcStep,m_16x16buf,16, &cost, 0);
if(cost.sum > m_SkippedThreshold) return false;
break;
case sad:
GetCost<Mb16x16,IntegerPixIn,SAD>(pSrc,m_SrcStep,m_16x16buf,16, &cost, 0);
if(cost.sum > m_SkippedThreshold) return false;
break;
case sadt:
GetCost<Mb16x16,IntegerPixIn,SADT>(pSrc,m_SrcStep,m_16x16buf,16, &cost, 0);
if(cost.sum > m_SkippedThreshold) return false;
break;
default:
assert(false);
}
return true;
}
bool MeBase::EstimateSkippedBidir()
{
const Ipp8u *pSrc, *pRef;
Ipp32s offset;
MeCost cost;
pSrc=m_pSrcFrameY+16*m_CurMB.y*m_SrcStep+16*m_CurMB.x;
offset = 16*(m_CurMB.x + m_CurMB.y*m_RefStep);
pRef = m_MePar->pRefFY[0] + offset;
Interpolate(pRef,m_RefStep,m_16x16buf,16, m_CurPrediction);
pRef = m_MePar->pRefBY[0] + offset;
Interpolate(pRef,m_RefStep,m_16x16bufB,16, m_CurPredictionB);
ippiAverage16x16_8u_C1R(m_16x16buf, 16, m_16x16bufB, 16, m_bufAvrg, 16);
switch(m_MePar->SkippedMetrics)
{
case maxad:
GetCost<Mb16x16,IntegerPixIn,MAXAD>(pSrc,m_SrcStep,m_bufAvrg,16, &cost, 0);
if(cost.sum > m_SkippedThreshold) return false;
break;
case sad:
GetCost<Mb16x16,IntegerPixIn,SAD>(pSrc,m_SrcStep,m_bufAvrg,16, &cost, 0);
if(cost.sum > m_SkippedThreshold) return false;
break;
case sadt:
GetCost<Mb16x16,IntegerPixIn,SADT>(pSrc,m_SrcStep,m_bufAvrg,16, &cost, 0);
if(cost.sum > m_SkippedThreshold) return false;
break;
default:
assert(false);
}
return true;
}
void MeBase::EstimateMB()
{
Ipp32s CostBeforeRefinement = IPP_MAX_32S;
MeMV MvBeforeRefinement(0);
predicted = true;
refined = false;
m_BlockIdx = 0; //16x16
m_BestCost[0] = IPP_MAX_32S;
MeInnerParams* inPars = m_MePar->GetMeInnerParams();
if(m_MePar->MbPart & Mb16x16){
//1 16x16
if(inPars->UseMvPrediction == 1){
//1 prediction
// subset A, median
EstimatePoint<Mb16x16,IntegerPixIn>(m_CurPrediction);
// subset B
EstimatePoint<Mb16x16,IntegerPixIn>(0);
EstimatePoint<Mb16x16,IntegerPixIn>(GetAMV());
EstimatePoint<Mb16x16,IntegerPixIn>(GetBMV());
EstimatePoint<Mb16x16,IntegerPixIn>(GetCMV());
if(m_BestCost[0]<GetT2()) return;
//1 refine prediction
predicted = false;
refined = true;
if(RefineSearch<Mb16x16, IntegerPixIn>()){
return; //should quarter pixel search be added here???
}
//continue by full search
refined = false;
CostBeforeRefinement = m_BestCost[0];
MvBeforeRefinement = m_BestMV[0];
}
//1 full search
m_BestMV[0] = 0; //start point to search
m_BestCost[0] = IPP_MAX_32S;
if(inPars->UseDownSampledImageForSearch == 0){
//integer pixel search
FullSearch<Mb16x16, IntegerPixIn>(m_SearchRangeX,m_SearchRangeY);
}else{
//down sampled pixel search
FullSearch<Mb16x16, QuadPixIn>(m_SearchRangeX, m_SearchRangeY);
m_BestCost[0] = IPP_MAX_32S;
RefineSearch<Mb16x16, QuadPixIn>();
if(CostBeforeRefinement<m_BestCost[0]){
//sometimes prediction gives better results than down sampled search
m_BestCost[0]=CostBeforeRefinement;
m_BestMV[0] = MvBeforeRefinement;
}
}
//1 quarter pixel search
if(m_MePar->PixelType == QuarterPixel)
RefineSearch<Mb16x16, QuarterPixIn>();
if(m_MePar->PixelType == HalfPixel)
RefineSearch<Mb16x16, HalfPixIn>();
}
if(m_MePar->MbPart & Mb8x8){
//1 8x8
//1 full search
m_BlockIdx = 0; //it is necessary to choose start MV
m_BestMV[0] = 0; //start point to search
ResetBestCost();
MeInnerParams * inPars = m_MePar->GetMeInnerParams();
if(inPars->UseDownSampledImageForSearch == 0){
//integer pixel search
FullSearch<Mb4x8x8, IntegerPixIn>(m_SearchRangeX,m_SearchRangeY);
}else{
//down sampled pixel search
FullSearch<Mb4x8x8, QuadPixIn>(m_SearchRangeX, m_SearchRangeY);
//refine each block
ResetBestCost();
m_BlockIdx = 0;
RefineSearch<Mb16x16, QuadPixIn>();
for(m_BlockIdx=1; m_BlockIdx<5; m_BlockIdx++){
RefineSearch<Mb8x8, QuadPixIn>();
}
}
//get sum of sad
Ipp32s sum8=0;
for(Ipp32s i=1; i<5; i++){
sum8+=m_BestCost[i];
}
//1 16x16 vs 8x8 decision.
// TODO: MVs cost should be added!
if(m_BestCost[0] < sum8 + 100){
//16x16
}
else{
//8x8
m_BestCost[0] = sum8;
}
}
}
inline void MeBase::Interpolate(const Ipp8u* pSrc,Ipp32s srcStep,Ipp8u* pDst,Ipp32s dstStep, MeMV mv)
{
IppVCInterpolate_8u par;
par.pSrc = pSrc+(mv.y/4)*srcStep+mv.x/4;
par.srcStep = srcStep;
par.pDst = pDst;
par.dstStep = dstStep;
par.dx = 3&mv.x;
par.dy = 3&mv.y;
par.roiSize.width = 16;
par.roiSize.height= 16;
par.roundControl = 0;
m_MePar->Interpolation == Vc1QpBicubic ?
ippiInterpolateQPBicubic_VC1_8u_C1R(&par):
ippiInterpolateQPBilinear_VC1_8u_C1R(&par);
}
void MeBase::MakeMbModeDecision()
{
//Costs calculated by Hadamard transform are not comparable to costs calculated by SAD!
Ipp16s bufDiff[256];
Ipp16s bufHDMR[64];
if(mbSkippedStatus != non_skipped)
{
MeCost cost;
const Ipp8u *pSrc=m_pSrcFrameY+16*m_CurMB.y*m_SrcStep+16*m_CurMB.x;
switch(mbSkippedStatus)
{
case skipped_forward:
m_ResMB[m_adr].MbType = MbFrw_Skipped;
//GetCost<Mb16x16,IntegerPixIn,SAD>(pSrc,m_SrcStep,m_16x16buf,16, &cost, 0);
CalcCost<Mb16x16,IntegerPixIn>(pSrc,m_SrcStep,m_16x16buf,16, &cost,0,m_CostMetrics);
m_ResMB[m_adr].MbCosts[0] = cost.sum + WeightMV(m_CurPrediction);
m_ResMB[m_adr].MVs[0] = m_CurPrediction;
if(m_MePar->SearchDirection == bidir_search)
m_ResMB[m_adr].MVs[1] = m_MVDirectBW[m_adr];
return;
case skipped_backward:
m_ResMB[m_adr].MbType = MbBkw_Skipped;
//GetCost<Mb16x16,IntegerPixIn,SAD>(pSrc,m_SrcStep,m_16x16buf,16, &cost, 0);
CalcCost<Mb16x16,IntegerPixIn>(pSrc,m_SrcStep,m_16x16buf,16, &cost,0,m_CostMetrics);
m_ResMB[m_adr].MbCosts[0] = cost.sum + WeightMV(m_CurPredictionB);
m_ResMB[m_adr].MVs[0] = m_CurPredictionB;
m_ResMB[m_adr].MVs[1] = m_MVDirectFW[m_adr];
return;
case skipped_bidir:
m_ResMB[m_adr].MbType = MbBidir_Skipped;
//GetCost<Mb16x16,IntegerPixIn,SAD>(pSrc,m_SrcStep,m_bufAvrg,16, &cost, 0);
CalcCost<Mb16x16,IntegerPixIn>(pSrc,m_SrcStep,m_bufAvrg,16, &cost,0,m_CostMetrics);
m_ResMB[m_adr].MbCosts[0] = cost.sum + WeightMV(m_CurPrediction) + WeightMV(m_CurPredictionB) + 32;
m_ResMB[m_adr].MVs[0] = m_CurPrediction;
m_ResMB[m_adr].MVs[1] = m_CurPredictionB;
case direct:
m_ResMB[m_adr].MbType = MbDirect;
//GetCost<Mb16x16,IntegerPixIn,SAD>(pSrc,m_SrcStep,m_bufAvrg,16, &cost, 0);
CalcCost<Mb16x16,IntegerPixIn>(pSrc,m_SrcStep,m_bufAvrg,16, &cost,0,m_CostMetrics);
m_ResMB[m_adr].MbCosts[0] = cost.sum + WeightMV(m_CurPrediction) + WeightMV(m_CurPredictionB) + 32;
m_ResMB[m_adr].MVs[0] = m_MVDirectFW[m_adr];
m_ResMB[m_adr].MVs[1] = m_MVDirectBW[m_adr];
return;
default:
assert(0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -