|
|
|
|
@@ -1868,7 +1868,86 @@ void WelsMdIntraSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB*
|
|
|
|
|
pCurMb->pSadCost[0] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
//func pointer of inter MD for sub16x16 INTER MD for screen content coding
|
|
|
|
|
//
|
|
|
|
|
static inline void MergeSub16Me (const SWelsME& sSrcMe0, const SWelsME& sSrcMe1, SWelsME* pTarMe) {
|
|
|
|
|
memcpy (pTarMe, &sSrcMe0, sizeof (sSrcMe0)); // confirmed_safe_unsafe_usage
|
|
|
|
|
|
|
|
|
|
pTarMe->uiSadCost = sSrcMe0.uiSadCost + sSrcMe1.uiSadCost;//not precise cost since MVD cost is not the same
|
|
|
|
|
pTarMe->uiSatdCost = sSrcMe0.uiSatdCost + sSrcMe1.uiSatdCost;//not precise cost since MVD cost is not the same
|
|
|
|
|
}
|
|
|
|
|
static inline bool IsSameMv (const SMVUnitXY& sMv0, const SMVUnitXY& sMv1) {
|
|
|
|
|
return ((sMv0.iMvX == sMv1.iMvX) && (sMv0.iMvY == sMv1.iMvY));
|
|
|
|
|
}
|
|
|
|
|
static inline int32_t Mvd (const SMVUnitXY& sMv, const SMVUnitXY& sMvp) {
|
|
|
|
|
return (WELS_ABS (sMv.iMvX - sMvp.iMvX) + WELS_ABS (sMv.iMvY - sMvp.iMvY));
|
|
|
|
|
}
|
|
|
|
|
bool TryModeMerge (SMbCache* pMbCache, SWelsMD* pWelsMd, SMB* pCurMb) {
|
|
|
|
|
SWelsME* pMe8x8 = & (pWelsMd->sMe.sMe8x8[0]);
|
|
|
|
|
const bool bSameMv16x8_0 = IsSameMv (pMe8x8[0].sMv, pMe8x8[1].sMv);
|
|
|
|
|
const bool bSameMv16x8_1 = IsSameMv (pMe8x8[2].sMv, pMe8x8[3].sMv);
|
|
|
|
|
|
|
|
|
|
const bool bSameMv8x16_0 = IsSameMv (pMe8x8[0].sMv, pMe8x8[2].sMv);
|
|
|
|
|
const bool bSameMv8x16_1 = IsSameMv (pMe8x8[1].sMv, pMe8x8[3].sMv);
|
|
|
|
|
//need to consider iRefIdx when multi ref is available
|
|
|
|
|
const bool bSameRefIdx16x8_0 = true; //pMe8x8[0].iRefIdx == pMe8x8[1].iRefIdx;
|
|
|
|
|
const bool bSameRefIdx16x8_1 = true; //pMe8x8[2].iRefIdx == pMe8x8[3].iRefIdx;
|
|
|
|
|
const bool bSameRefIdx8x16_0 = true; //pMe8x8[0].iRefIdx == pMe8x8[2].iRefIdx;
|
|
|
|
|
const bool bSameRefIdx8x16_1 = true; //pMe8x8[1].iRefIdx == pMe8x8[3].iRefIdx;
|
|
|
|
|
const int32_t iSameMv = (bSameMv16x8_0 << 7) | (bSameRefIdx16x8_0 << 6) | (bSameMv16x8_1 << 5) |
|
|
|
|
|
(bSameRefIdx16x8_1 << 4) |
|
|
|
|
|
(bSameMv8x16_0 << 3) | (bSameRefIdx8x16_0 << 2) | (bSameMv8x16_1 << 1) | (bSameRefIdx8x16_1);
|
|
|
|
|
|
|
|
|
|
switch (iSameMv) {
|
|
|
|
|
case 0xF0:
|
|
|
|
|
pCurMb->uiMbType = MB_TYPE_16x8;
|
|
|
|
|
MergeSub16Me (pMe8x8[0], pMe8x8[1], & (pWelsMd->sMe.sMe16x8[0]));
|
|
|
|
|
MergeSub16Me (pMe8x8[2], pMe8x8[3], & (pWelsMd->sMe.sMe16x8[1]));
|
|
|
|
|
PredInter16x8Mv (pMbCache, 0, 0, & (pWelsMd->sMe.sMe16x8[0].sMvp));
|
|
|
|
|
PredInter16x8Mv (pMbCache, 8, 0, & (pWelsMd->sMe.sMe16x8[1].sMvp));
|
|
|
|
|
break;
|
|
|
|
|
case 0x0F:
|
|
|
|
|
pCurMb->uiMbType = MB_TYPE_8x16;
|
|
|
|
|
MergeSub16Me (pMe8x8[0], pMe8x8[2], & (pWelsMd->sMe.sMe8x16[0]));
|
|
|
|
|
MergeSub16Me (pMe8x8[1], pMe8x8[3], & (pWelsMd->sMe.sMe8x16[1]));
|
|
|
|
|
PredInter8x16Mv (pMbCache, 0, 0, & (pWelsMd->sMe.sMe8x16[0].sMvp));
|
|
|
|
|
PredInter8x16Mv (pMbCache, 4, 0, & (pWelsMd->sMe.sMe8x16[1].sMvp));
|
|
|
|
|
break;
|
|
|
|
|
case 0xFF:
|
|
|
|
|
//MERGE_16x16
|
|
|
|
|
//from test results of multiple sequences show that using the following 0x0F to merge 16x16
|
|
|
|
|
//for some seq there is BR saving some loss
|
|
|
|
|
//on the whole the BR will increase little bit
|
|
|
|
|
//to save complexity we decided not to merge 16x16 at present (10/12/2012)
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return (MB_TYPE_8x8 != pCurMb->uiMbType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void WelsMdInterFinePartitionVaaOnScreen (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, int32_t iBestCost) {
|
|
|
|
|
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pEnc;
|
|
|
|
|
SWelsMD* pWelsMd = (SWelsMD*)pMd;
|
|
|
|
|
SMbCache* pMbCache = &pSlice->sMbCacheInfo;
|
|
|
|
|
SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
|
|
|
|
|
int32_t iCostP8x8;
|
|
|
|
|
uint8_t uiMbSign = pEncCtx->pFuncList->pfGetMbSignFromInterVaa (&pEncCtx->pVaa->sVaaCalcInfo.pSad8x8[pCurMb->iMbXY][0]);
|
|
|
|
|
|
|
|
|
|
if (MBVAASIGN_FLAT == uiMbSign) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iCostP8x8 = WelsMdP8x8 (pEncCtx->pFuncList, pCurDqLayer, pWelsMd, pSlice);
|
|
|
|
|
if (iCostP8x8 < iBestCost) {
|
|
|
|
|
iBestCost = iCostP8x8;
|
|
|
|
|
pCurMb->uiMbType = MB_TYPE_8x8;
|
|
|
|
|
|
|
|
|
|
TryModeMerge (pMbCache, pWelsMd, pCurMb);
|
|
|
|
|
}
|
|
|
|
|
pWelsMd->iCostLuma = iBestCost;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace WelsSVCEnc
|
|
|
|
|
|