Add checking directional MV in ME initial point
This commit is contained in:
parent
8d11b28690
commit
99f3bd69c4
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user