Merge pull request #818 from sijchen/md_merge133
[Encoder MD] Add Inter Psub16 MD for screen content coding
This commit is contained in:
commit
758e89208e
@ -66,6 +66,15 @@ namespace WelsSVCEnc {
|
|||||||
|
|
||||||
#define NO_BEST_FRAC_PIX 1 // REFINE_ME_NO_BEST_HALF_PIXEL + ME_NO_BEST_QUAR_PIXEL
|
#define NO_BEST_FRAC_PIX 1 // REFINE_ME_NO_BEST_HALF_PIXEL + ME_NO_BEST_QUAR_PIXEL
|
||||||
|
|
||||||
|
//for vaa constants
|
||||||
|
#define MBVAASIGN_FLAT 15
|
||||||
|
#define MBVAASIGN_HOR1 3
|
||||||
|
#define MBVAASIGN_HOR2 12
|
||||||
|
#define MBVAASIGN_VER1 5
|
||||||
|
#define MBVAASIGN_VER2 10
|
||||||
|
#define MBVAASIGN_CMPX1 6
|
||||||
|
#define MBVAASIGN_CMPX2 9
|
||||||
|
|
||||||
extern const int32_t g_kiQpCostTable[52];
|
extern const int32_t g_kiQpCostTable[52];
|
||||||
extern const int8_t g_kiMapModeI16x16[7];
|
extern const int8_t g_kiMapModeI16x16[7];
|
||||||
//extern const int8_t g_kiMapModeI4x4[14];
|
//extern const int8_t g_kiMapModeI4x4[14];
|
||||||
|
@ -66,6 +66,8 @@ int32_t WelsMdP8x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWe
|
|||||||
/*static*/ void WelsMdInterInit (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb, const int32_t kiSliceFirstMbXY);
|
/*static*/ void WelsMdInterInit (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb, const int32_t kiSliceFirstMbXY);
|
||||||
/*static*/ void WelsMdInterFinePartition (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, int32_t bestCost);
|
/*static*/ void WelsMdInterFinePartition (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, int32_t bestCost);
|
||||||
/*static*/ void WelsMdInterFinePartitionVaa (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, int32_t bestCost);
|
/*static*/ void WelsMdInterFinePartitionVaa (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, int32_t bestCost);
|
||||||
|
/*static*/ void WelsMdInterFinePartitionVaaOnScreen (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb,
|
||||||
|
int32_t bestCost);
|
||||||
void WelsMdInterMbRefinement (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
void WelsMdInterMbRefinement (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||||
bool WelsMdFirstIntraMode (void* pEnc, void* pMd, SMB* pCurMb, SMbCache* pMbCache);
|
bool WelsMdFirstIntraMode (void* pEnc, void* pMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||||
//bool svc_md_first_intra_mode_constrained(void* pEnc, void* pMd, SMB* pCurMb, SMbCache *pMbCache);
|
//bool svc_md_first_intra_mode_constrained(void* pEnc, void* pMd, SMB* pCurMb, SMbCache *pMbCache);
|
||||||
|
@ -2470,6 +2470,9 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
|||||||
pFeatureSearchPreparation->iHighFreMbCount = 0;
|
pFeatureSearchPreparation->iHighFreMbCount = 0;
|
||||||
|
|
||||||
if (P_SLICE == pCtx->eSliceType) {
|
if (P_SLICE == pCtx->eSliceType) {
|
||||||
|
//MD related func pointers
|
||||||
|
pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaaOnScreen;
|
||||||
|
|
||||||
//calculate bFMESwitchFlag
|
//calculate bFMESwitchFlag
|
||||||
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
|
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
|
||||||
const int32_t kiMbSize = pCurLayer->iMbHeight * pCurLayer->iMbWidth;
|
const int32_t kiMbSize = pCurLayer->iMbHeight * pCurLayer->iMbWidth;
|
||||||
|
@ -1868,7 +1868,86 @@ void WelsMdIntraSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB*
|
|||||||
pCurMb->pSadCost[0] = 0;
|
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
|
} // namespace WelsSVCEnc
|
||||||
|
Loading…
Reference in New Issue
Block a user