📄 umc_h264_me.cpp
字号:
Ipp32s left,
Ipp32s right,
Ipp32s up,
Ipp32s down,
Ipp32u ref_constraint,
Ipp32u qp,
Ipp32s uMBy,
const H264EncoderParams* info,
Ipp8u* me_map)
: max_vec_number_(MVS_TABLE_SIZE)
, mvp_(mvp)
, ref_constraint_(ref_constraint)
, left_(left)
, right_(right)
, up_(up)
, down_(down)
, uMBy_(uMBy)
, info_(info)
, start_vector_(0)
, map_(me_map)
{
pRDQM_ = glob_RDQM[qp];
reset_map();
}
void reset_map()
{
Ipp32s size = (2*info_->me_search_x + 1)* (2*info_->me_search_y + 1);
ippsZero_8u(map_, size);
start_vector_ = 0;
}
Ipp32s AdvCalcOneMBSAD(const PixType* pRef,
const PixType* pCur,
Ipp32s pitchPixels,
Ipp32s x,
Ipp32s y)
{
Ipp8u* map = 0;
if (x >= left_ && x <= right_ && y >= up_ && y <= down_)
{
Ipp32s index = (x - left_) + (y - up_)*(info_->me_search_x*2 + 1);
map = &map_[index];
if (*map)
{
return -1;
}
*map = 1;
} else {
return -1;
}
Ipp32s owner = start_vector_;
start_vector_++;
vectors_[owner].CalcOneMBSAD(pRef,pCur,pitchPixels,x, y);
Ipp32u constraint_sad = MVConstraint(x*4 - mvp_.mvx,
y*4 - mvp_.mvy, pRDQM_)
+ ref_constraint_;
vectors_[owner].s_sads += constraint_sad;
return owner;
}
void SetStartVector(Ipp32s start)
{
start_vector_ = start;
}
Ipp32s GetMinDirection(Ipp32s *directions, Ipp32s maxdirs)
{
Ipp32u min_sad = ME_MAX_SAD*4+1;
Ipp32s min_dir = -1;
for (Ipp32s k = 0; k <= maxdirs; k++)
{
if (directions[k] == -1)
continue;
Ipp32u cur_sad = vectors_[directions[k]].s_sads;
if (cur_sad < min_sad)
{
min_dir = k;
min_sad = cur_sad;
}
}
if (min_dir == -1)
return -1;
VM_ASSERT(min_dir != -1);
return min_dir;
}
H264MotionVector mvp_;
Ipp32u ref_constraint_;
MEVector<PixType> vectors_[MVS_TABLE_SIZE];
Ipp32s max_vec_number_;
Ipp16s *pRDQM_;
Ipp32s left_;
Ipp32s right_;
Ipp32s up_;
Ipp32s down_;
Ipp32s uMBy_;
Ipp8u* map_;
const H264EncoderParams* info_;
Ipp32s start_vector_;
};
template <class PixType>
void MEVector<PixType>::CalcOneMBSAD(const PixType* pRef,
const PixType* pCur,
Ipp32s pitchPixels,
Ipp32s rx,
Ipp32s ry)
{
x = rx;
y = ry;
pRef = MVADJUST(pRef, pitchPixels, x, y);
#if 0 // TODO ADB
//#ifdef NEW_INTERPOLATE
PixType *const pInterpBuf = curr_slice->m_pMBEncodeBuffer;
Interpolate(pRef, pitchPixels, pInterpBuf, 16, 0,
0, size16x16, y << SUB_PEL_SHIFT, uMBy*16, 0);
ippiSAD16x16Blocks8x8(pCur, pitchPixels*sizeof(PixType), pInterpBuf, 16*sizeof(PixType), sads, 0);
#else
SAD16x16Blocks8x8(pCur, pitchPixels*sizeof(PixType), pRef, pitchPixels*sizeof(PixType), sads);
#endif
s_sads = sads[3] + sads[2] + sads[1] + sads[0];
}
inline void FindAndStoreBestInfo(T_RefIdx ref_idx,
Ipp32u ThisSAD[41],
H264MotionVector tempPredictedMV[41],
ME_Info me_info[41],
Ipp32s mvx, Ipp32s mvy,
Ipp32u ref_constraint,
Ipp16s *pRDQM,
Ipp32s me_split_8x8s)
{
Ipp32u tempSAD;
if (me_split_8x8s)
{
tempSAD = MVConstraint(mvx - tempPredictedMV[SB_8x8_TL].mvx,
mvy - tempPredictedMV[SB_8x8_TL].mvy, pRDQM) + ref_constraint;
tempSAD += ThisSAD[0];
// Accumulate SAD and MVs for 8x8 blocks
if (tempSAD < me_info[SB_8x8_TL].sad)
{
me_info[SB_8x8_TL].sad = tempSAD;
me_info[SB_8x8_TL].mv.mvx = (Ipp16s)mvx;
me_info[SB_8x8_TL].mv.mvy = (Ipp16s)mvy;
me_info[SB_8x8_TL].ref_idx = ref_idx;
me_info[SB_8x8_TL].predicted_mv = tempPredictedMV[SB_8x8_TL];
VM_ASSERT(VINTRANGE(mvx >> SUB_PEL_SHIFT));
VM_ASSERT(VINTRANGE(mvy >> SUB_PEL_SHIFT));
}
for (Ipp32s block = 33; block < 36; ++block)
{ // 4 - 8x8 blocks
tempSAD = ThisSAD[block-32];
// Accumulate SAD and MVs for 8x8 blocks
if (tempSAD < me_info[block].sad)
{
me_info[block].sad = tempSAD;
me_info[block].mv.mvx = (Ipp16s)mvx;
me_info[block].mv.mvy = (Ipp16s)mvy;
me_info[block].ref_idx = ref_idx;
me_info[block].predicted_mv = tempPredictedMV[block];
VM_ASSERT(VINTRANGE(mvx >> SUB_PEL_SHIFT));
VM_ASSERT(VINTRANGE(mvy >> SUB_PEL_SHIFT));
}
} // block
// Unroll the loop; removes table lookups
Ipp32u sad_8x16_l = ((Ipp32u)ThisSAD[0]+(Ipp32u)ThisSAD[2]);
tempSAD = MVConstraint(mvx - tempPredictedMV[SB_8x16_L].mvx,
mvy - tempPredictedMV[SB_8x16_L].mvy, pRDQM)
+ ref_constraint + sad_8x16_l;
if (tempSAD < me_info[SB_8x16_L].sad)
{
me_info[SB_8x16_L].sad = tempSAD;
me_info[SB_8x16_L].mv.mvx = (Ipp16s)mvx;
me_info[SB_8x16_L].mv.mvy = (Ipp16s)mvy;
me_info[SB_8x16_L].ref_idx = ref_idx;
me_info[SB_8x16_L].predicted_mv = tempPredictedMV[SB_8x16_L];
}
Ipp32u sad_8x16_r = ((Ipp32u)ThisSAD[1]+(Ipp32u)ThisSAD[3]);
tempSAD = MVConstraint(mvx - tempPredictedMV[SB_8x16_R].mvx,
mvy - tempPredictedMV[SB_8x16_R].mvy, pRDQM)
+ ref_constraint + sad_8x16_r;
if (tempSAD < me_info[SB_8x16_R].sad)
{
me_info[SB_8x16_R].sad = tempSAD;
me_info[SB_8x16_R].mv.mvx = (Ipp16s)mvx;
me_info[SB_8x16_R].mv.mvy = (Ipp16s)mvy;
me_info[SB_8x16_R].ref_idx = ref_idx;
me_info[SB_8x16_R].predicted_mv = tempPredictedMV[SB_8x16_R];
}
tempSAD = MVConstraint(mvx - tempPredictedMV[SB_16x8_T].mvx,
mvy - tempPredictedMV[SB_16x8_T].mvy, pRDQM)
+ ref_constraint;
tempSAD += ((Ipp32u)ThisSAD[0]+(Ipp32u)ThisSAD[1]);
if (tempSAD < me_info[SB_16x8_T].sad)
{
me_info[SB_16x8_T].sad = tempSAD;
me_info[SB_16x8_T].mv.mvx = (Ipp16s)mvx;
me_info[SB_16x8_T].mv.mvy = (Ipp16s)mvy;
me_info[SB_16x8_T].ref_idx = ref_idx;
me_info[SB_16x8_T].predicted_mv = tempPredictedMV[SB_16x8_T];
}
tempSAD = MVConstraint(mvx - tempPredictedMV[SB_16x8_B].mvx,
mvy - tempPredictedMV[SB_16x8_B].mvy, pRDQM)
+ ref_constraint;
tempSAD += ((Ipp32u)ThisSAD[2]+(Ipp32u)ThisSAD[3]);
if (tempSAD < me_info[SB_16x8_B].sad)
{
me_info[SB_16x8_B].sad = tempSAD;
me_info[SB_16x8_B].mv.mvx = (Ipp16s)mvx;
me_info[SB_16x8_B].mv.mvy = (Ipp16s)mvy;
me_info[SB_16x8_B].ref_idx = ref_idx;
me_info[SB_16x8_B].predicted_mv = tempPredictedMV[SB_16x8_B];
}
}
tempSAD = MVConstraint(mvx - tempPredictedMV[SB_16x16].mvx,
mvy - tempPredictedMV[SB_16x16].mvy, pRDQM)
+ ref_constraint;
tempSAD += ThisSAD[0] + ThisSAD[1] + ThisSAD[2] + ThisSAD[3];
if (tempSAD < me_info[SB_16x16].sad)
{
me_info[SB_16x16].sad = tempSAD;
me_info[SB_16x16].mv.mvx = (Ipp16s)mvx;
me_info[SB_16x16].mv.mvy = (Ipp16s)mvy;
me_info[SB_16x16].ref_idx = ref_idx;
me_info[SB_16x16].predicted_mv = tempPredictedMV[SB_16x16];
}
}
typedef enum
{
MV_SEARCH_TYPE_FULL = 0,
MV_SEARCH_TYPE_CLASSIC_LOG = 1,
MV_SEARCH_TYPE_LOG = 2,
MV_SEARCH_TYPE_EPZS = 3,
MV_SEARCH_TYPE_FULL_ORTHOGONAL = 4,
MV_SEARCH_TYPE_LOG_ORTHOGONAL = 5,
MV_SEARCH_TYPE_TTS = 6,
MV_SEARCH_TYPE_NEW_EPZS = 7,
} MVS_Type;
template <class PixType, class CoeffsType>
void H264CoreEncoder<PixType,CoeffsType>::CMEOneMB_Finder(
H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice,
Ipp32u uMB,
T_RefIdx ref_idx,
const H264EncoderFrame<PixType> *pRefFrame,
const Ipp8s Field,
bool , // bBSlice,
H264MotionVector tempPredictedMV[41],
ME_Info me_info[41],
Ipp32s left,
Ipp32s right,
Ipp32s up,
Ipp32s down,
Ipp32s startX,
Ipp32s startY
)
{
H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
T_EncodeMBOffsets *pMBOffset = &m_pMBOffsets[uMB];
Ipp32s is_cur_mb_field = curr_slice->m_is_cur_mb_field;
PixType* pCurrent = cur_mb.mbPtr;
PixType* pPrev = pRefFrame->m_pYPlane + pMBOffset->uLumaOffset[m_is_cur_pic_afrm][is_cur_mb_field] + curr_slice->m_InitialOffset[Field];
PixType* pCur, * pRef; // Working pointers
Ipp32s pitchPixels = cur_mb.mbPitchPixels;
Ipp32s iQP = getLumaQP51(curr_slice->m_cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.bit_depth_luma);
Ipp16s *pRDQM = glob_RDQM[iQP];
Ipp32u ThisSAD[41];
Ipp32u ref_constraint = RefConstraint(ref_idx, curr_slice->m_NumRefsInL0List, pRDQM);
if (cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_BACKWARD)
{
ref_constraint = RefConstraint(ref_idx, curr_slice->m_NumRefsInL1List, pRDQM);
}
Base_Search<PixType> search(tempPredictedMV[SB_16x16], left,right,up,down, ref_constraint, iQP, curr_slice->m_CurMB_Y, &m_info
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -