[Encoder MD] Add Inter Psub16 MD for screen content coding
This commit is contained in:
parent
6a295d5e8e
commit
4bd6a3a6e8
@ -66,6 +66,15 @@ namespace WelsSVCEnc {
|
||||
|
||||
#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 int8_t g_kiMapModeI16x16[7];
|
||||
//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 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 WelsMdInterFinePartitionVaaOnScreen (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb,
|
||||
int32_t bestCost);
|
||||
void WelsMdInterMbRefinement (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, 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);
|
||||
|
@ -2457,6 +2457,9 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
||||
pFeatureSearchPreparation->iHighFreMbCount = 0;
|
||||
|
||||
if (P_SLICE == pCtx->eSliceType) {
|
||||
//MD related func pointers
|
||||
pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaaOnScreen;
|
||||
|
||||
//calculate bFMESwitchFlag
|
||||
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
|
||||
const int32_t kiMbSize = pCurLayer->iMbHeight * pCurLayer->iMbWidth;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user