Add checking directional MV in ME initial point

This commit is contained in:
sijchen 2014-03-24 14:16:16 +08:00
parent 8d11b28690
commit 99f3bd69c4
5 changed files with 109 additions and 39 deletions

View File

@ -140,6 +140,12 @@ bool WelsMeSadCostSelect (int32_t* pSadCost, const uint16_t* kpMvdCost, int32_t*
void CalculateSatdCost( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride );
void NotCalculateSatdCost( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride );
bool CheckDirectionalMv(PSampleSadSatdCostFunc pSad, void * vpMe,
const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride,
int32_t& iBestSadCost);
bool CheckDirectionalMvFalse(PSampleSadSatdCostFunc pSad, void * vpMe,
const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride,
int32_t& iBestSadCost);
inline void SetMvWithinMvRange( const int32_t kiMbWidth, const int32_t kiMbHeight, const int32_t kiMbX, const int32_t kiMbY,
const int32_t kiMaxMvRange,
@ -151,6 +157,14 @@ inline void SetMvWithinMvRange( const int32_t kiMbWidth, const int32_t kiMbHeigh
pMvMax->iMvY = WELS_MIN( ((kiMbHeight - kiMbY)<<4) - INTPEL_NEEDED_MARGIN, kiMaxMvRange);
}
inline bool CheckMvInRange( const int16_t kiCurrentMv, const int16_t kiMinMv, const int16_t kiMaxMv )
{
return ((kiCurrentMv >= kiMinMv) && (kiCurrentMv < kiMaxMv));
}
inline bool CheckMvInRange( const SMVUnitXY ksCurrentMv, const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv )
{
return (CheckMvInRange(ksCurrentMv.iMvX, ksMinMv.iMvX, ksMaxMv.iMvX)
&& CheckMvInRange(ksCurrentMv.iMvY, ksMinMv.iMvY, ksMaxMv.iMvY));
}
}
#endif

View File

@ -136,6 +136,9 @@ typedef int32_t (*PIntraPred8x8Combined3Func) (uint8_t*, int32_t, uint8_t*, int3
typedef void (*PMotionSearchFunc) (SWelsFuncPtrList* pFuncList, void* pCurDqLayer, void* pMe,
void* pSlice); // here after reset all function pointers, will set as right parameter type
typedef void (*PCalculateSatdFunc) ( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride );
typedef bool (*PCheckDirectionalMv) (PSampleSadSatdCostFunc pSad, void * vpMe,
const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride,
int32_t& iBestSadCost);
#define MAX_BLOCK_TYPE 5 // prev 7
typedef struct TagSampleDealingFunc {
@ -188,6 +191,7 @@ struct TagWelsFuncPointerList {
PMotionSearchFunc
pfMotionSearch; //svc_encode_slice.c svc_mode_decision.c svc_enhance_layer_md.c svc_base_layer_md.c
PCalculateSatdFunc pfCalculateSatd;
PCheckDirectionalMv pfCheckDirectionalMv;
PCopyFunc pfCopy16x16Aligned; //svc_encode_slice.c svc_mode_decision.c svc_base_layer_md.c
PCopyFunc pfCopy16x16NotAligned; //md.c

View File

@ -2515,6 +2515,7 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
pFuncList->pfMotionSearch = WelsMotionEstimateSearch;
pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode;
pFuncList->sSampleDealingFuncs.pfMeCost = pCtx->pFuncList->sSampleDealingFuncs.pfSampleSatd;
pFuncList->pfCheckDirectionalMv = CheckDirectionalMvFalse;
if (kbHighestSpatialLayer) {
pFuncList->pfCalculateSatd = NotCalculateSatdCost;
pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaa;

View File

@ -970,24 +970,31 @@ void WelsMdIntraMb (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCach
WelsMdIntraSecondaryModesEnc (pEncCtx, pWelsMd, pCurMb, pMbCache);
}
static inline void InitMe(const SWelsMD& sWelsMd, const int32_t iBlockSize, uint8_t* pEnc, uint8_t* pRef,
SWelsME& sWelsMe )
{
sWelsMe.iCurMeBlockPixX = sWelsMd.iMbPixX;
sWelsMe.iCurMeBlockPixY = sWelsMd.iMbPixY;
sWelsMe.uiPixel = iBlockSize;
sWelsMe.pMvdCost = sWelsMd.pMvdCost;
sWelsMe.pEncMb = pEnc;
sWelsMe.pRefMb = sWelsMe.pColoRefMb = pRef;
}
int32_t WelsMdP16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWelsMd, SSlice* pSlice, SMB* pCurMb) {
SMbCache* pMbCache = &pSlice->sMbCacheInfo;
SWelsME* sMe16x16 = &pWelsMd->sMe.sMe16x16;
SWelsME* pMe16x16 = &pWelsMd->sMe.sMe16x16;
uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail;
const int32_t kiMbWidth = pCurLayer->iMbWidth; // for assign once
const int32_t kiMbHeight = pCurLayer->iMbHeight;
sMe16x16->iCurMeBlockPixX = pWelsMd->iMbPixX;
sMe16x16->iCurMeBlockPixY = pWelsMd->iMbPixY;
sMe16x16->uiPixel = BLOCK_16x16;
sMe16x16->pMvdCost = pWelsMd->pMvdCost;
sMe16x16->pEncMb = pMbCache->SPicData.pEncMb[0];
sMe16x16->pRefMb = pMbCache->SPicData.pRefMb[0];
sMe16x16->uSadPredISatd.uiSadPred = pWelsMd->iSadPredMb;
InitMe(*pWelsMd, BLOCK_16x16, pMbCache->SPicData.pEncMb[0], pMbCache->SPicData.pRefMb[0],
*pMe16x16 );
//not putting the line below into InitMe to avoid judging mode in InitMe
pMe16x16->uSadPredISatd.uiSadPred = pWelsMd->iSadPredMb;
pSlice->uiMvcNum = 0;
pSlice->sMvc[pSlice->uiMvcNum++] = sMe16x16->sMvBase;
pSlice->sMvc[pSlice->uiMvcNum++] = pMe16x16->sMvBase;
//spatial motion vector predictors
if (uiNeighborAvail & LEFT_MB_POS) { //left available
pSlice->sMvc[pSlice->uiMvcNum++] = (pCurMb - 1)->sP16x16Mv;
@ -1011,30 +1018,31 @@ int32_t WelsMdP16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWe
}
}
PredMv (&pMbCache->sMvComponents, 0, 4, 0, & (sMe16x16->sMvp));
pFunc->pfMotionSearch (pFunc, pCurLayer, sMe16x16, pSlice);
// update_p16x16_motion2cache(pMbCache, pWelsMd->uiRef, &(sMe16x16->mv));
PredMv (&pMbCache->sMvComponents, 0, 4, 0, & (pMe16x16->sMvp));
pFunc->pfMotionSearch (pFunc, pCurLayer, pMe16x16, pSlice);
// update_p16x16_motion2cache(pMbCache, pWelsMd->uiRef, &(pMe16x16->mv));
pCurMb->sP16x16Mv = sMe16x16->sMv;
pCurLayer->pDecPic->sMvList[pCurMb->iMbXY] = sMe16x16->sMv;
pCurMb->sP16x16Mv = pMe16x16->sMv;
pCurLayer->pDecPic->sMvList[pCurMb->iMbXY] = pMe16x16->sMv;
return sMe16x16->uiSatdCost;
return pMe16x16->uiSatdCost;
}
int32_t WelsMdP16x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWelsMd, SSlice* pSlice) {
SMbCache* pMbCache = &pSlice->sMbCacheInfo;
int32_t iStrideEnc = pCurDqLayer->iEncStride[0];
int32_t iStrideRef = pCurDqLayer->pRefPic->iLineSize[0];
SWelsME* sMe16x8;
int32_t i = 0;
int32_t i = 0, iPixelY;
int32_t iCostP16x8 = 0;
do {
sMe16x8 = &pWelsMd->sMe.sMe16x8[i];
sMe16x8->uiPixel = BLOCK_16x8;
sMe16x8->pMvdCost = pWelsMd->pMvdCost;
sMe16x8->pEncMb = pMbCache->SPicData.pEncMb[0] + ((i << 3) * iStrideEnc);
sMe16x8->pRefMb = pMbCache->SPicData.pRefMb[0] + ((i << 3) * iStrideRef);
iPixelY = (i << 3);
InitMe(*pWelsMd, BLOCK_16x8,
pMbCache->SPicData.pEncMb[0] + (iPixelY * iStrideEnc),
pMbCache->SPicData.pRefMb[0] + (iPixelY * iStrideRef),
*sMe16x8 );
//not putting the lines below into InitMe to avoid judging mode in InitMe
sMe16x8->iCurMeBlockPixY = pWelsMd->iMbPixY + iPixelY;
sMe16x8->uSadPredISatd.uiSadPred = pWelsMd->iSadPredMb >> 1;
pSlice->sMvc[0] = sMe16x8->sMvBase;
@ -1051,16 +1059,17 @@ int32_t WelsMdP16x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pW
int32_t WelsMdP8x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWelsMd, SSlice* pSlice) {
SMbCache* pMbCache = &pSlice->sMbCacheInfo;
SWelsME* sMe8x16;
int32_t i = 0;
int32_t i = 0, iPixelX;
int32_t iCostP8x16 = 0;
do {
iPixelX = (i << 3);
sMe8x16 = &pWelsMd->sMe.sMe8x16[i];
sMe8x16->uiPixel = BLOCK_8x16;
sMe8x16->pMvdCost = pWelsMd->pMvdCost;
sMe8x16->pEncMb = pMbCache->SPicData.pEncMb[0] + (i << 3);
sMe8x16->pRefMb = pMbCache->SPicData.pRefMb[0] + (i << 3);
InitMe(*pWelsMd, BLOCK_8x16,
pMbCache->SPicData.pEncMb[0] + iPixelX,
pMbCache->SPicData.pRefMb[0] + iPixelX,
*sMe8x16 );
//not putting the lines below into InitMe to avoid judging mode in InitMe
sMe8x16->iCurMeBlockPixX = pWelsMd->iMbPixX + iPixelX;
sMe8x16->uSadPredISatd.uiSadPred = pWelsMd->iSadPredMb >> 1;
pSlice->sMvc[0] = sMe8x16->sMvBase;
@ -1091,16 +1100,16 @@ int32_t WelsMdP8x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWe
iStrideRef = iPixelX + ( iPixelY * iLineSizeRef);
sMe8x8 = &pWelsMd->sMe.sMe8x8[i];
InitMe(*pWelsMd, BLOCK_8x8,
pMbCache->SPicData.pEncMb[0] + iStrideEnc,
pMbCache->SPicData.pRefMb[0] + iStrideRef,
*sMe8x8 );
//not putting these three lines below into InitMe to avoid judging mode in InitMe
sMe8x8->iCurMeBlockPixX = pWelsMd->iMbPixX + iPixelX;
sMe8x8->iCurMeBlockPixY = pWelsMd->iMbPixY + iPixelY;
sMe8x8->uiPixel = BLOCK_8x8;
sMe8x8->pMvdCost = pWelsMd->pMvdCost;
sMe8x8->pEncMb = pMbCache->SPicData.pEncMb[0] + iStrideEnc;
sMe8x8->pRefMb = pMbCache->SPicData.pRefMb[0] + iStrideRef;
sMe8x8->uSadPredISatd.uiSadPred = pWelsMd->iSadPredMb >> 2;
pSlice->sMvc[0] = sMe8x8->sMvBase;
pSlice->uiMvcNum = 1;
@ -1856,4 +1865,6 @@ void WelsMdIntraSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB*
pCurMb->pSadCost[0] = 0;
}
} // namespace WelsSVCEnc

View File

@ -39,7 +39,7 @@
*/
#include "sample.h"
#include "svc_motion_estimate.h"
namespace WelsSVCEnc {
@ -141,6 +141,13 @@ bool WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
}
}
if ( pFuncList->pfCheckDirectionalMv
(pSad, pMe, ksMvStartMin, ksMvStartMax, iStrideEnc, iStrideRef, iSadCost) ) {
sMv = pMe->sDirectionalMv;
pRefMb = &pMe->pColoRefMb[sMv.iMvY * iStrideRef + sMv.iMvX];
iBestSadCost = iSadCost;
}
UpdateMeResults( sMv, iBestSadCost, pRefMb, pMe );
if ( iBestSadCost < static_cast<int32_t>(pMe->uSadPredISatd.uiSadPred) ) {
//Initial point early Stop
@ -237,4 +244,37 @@ void NotCalculateSatdCost( PSampleSadSatdCostFunc pSatd, void * vpMe, const int3
{
}
bool CheckDirectionalMv(PSampleSadSatdCostFunc pSad, void * vpMe,
const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride,
int32_t& iBestSadCost)
{
SWelsME* pMe = static_cast<SWelsME *>(vpMe);
const int16_t kiMvX = pMe->sDirectionalMv.iMvX;
const int16_t kiMvY = pMe->sDirectionalMv.iMvY;
//Check MV from scrolling detection
if ( (BLOCK_16x16!=pMe->uiPixel) //scrolled_MV with P16x16 is checked SKIP checking function
&& ( kiMvX | kiMvY ) //(0,0) checked in ordinary initial point checking
&& CheckMvInRange( pMe->sDirectionalMv, ksMinMv, ksMaxMv ) )
{
uint8_t* pRef = &pMe->pColoRefMb[kiMvY * kiRefStride + kiMvX];
uint32_t uiCurrentSadCost = pSad( pMe->pEncMb, kiEncStride, pRef, kiRefStride ) +
COST_MVD(pMe->pMvdCost, (kiMvX<<2) - pMe->sMvp.iMvX, (kiMvY<<2) - pMe->sMvp.iMvY );
if( uiCurrentSadCost < pMe->uiSadCost )
{
iBestSadCost = uiCurrentSadCost;
return true;
}
}
return false;
}
bool CheckDirectionalMvFalse(PSampleSadSatdCostFunc pSad, void * vpMe,
const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride,
int32_t& iBestSadCost)
{
return false;
}
} // namespace WelsSVCEnc