Add basic cross search functions and its unit tests
This commit is contained in:
parent
54f5f34725
commit
bbe016543f
@ -67,7 +67,7 @@ uint32_t uiSatdCost; /* satd + lm * nbits */
|
||||
uint32_t uiSadCostThreshold;
|
||||
int32_t iCurMeBlockPixX;
|
||||
int32_t iCurMeBlockPixY;
|
||||
uint8_t uiPixel; /* PIXEL_WxH */
|
||||
uint8_t uiBlockSize; /* BLOCK_WxH */
|
||||
uint8_t uiReserved;
|
||||
|
||||
uint8_t* pEncMb;
|
||||
@ -147,7 +147,14 @@ 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,
|
||||
void LineFullSearch_c( PSampleSadSatdCostFunc pSad, void *vpMe,
|
||||
uint16_t* pMvdTable, const int32_t kiFixedMvd,
|
||||
const int32_t kiEncStride, const int32_t kiRefStride,
|
||||
const int32_t kiMinPos, const int32_t kiMaxPos,
|
||||
const bool bVerticalSearch );
|
||||
void WelsMotionCrossSearch(SWelsFuncPtrList *pFuncList, SDqLayer* pCurLayer, SWelsME * pMe, const SSlice* pSlice);
|
||||
|
||||
inline void SetMvWithinIntegerMvRange( const int32_t kiMbWidth, const int32_t kiMbHeight, const int32_t kiMbX, const int32_t kiMbY,
|
||||
const int32_t kiMaxMvRange,
|
||||
SMVUnitXY* pMvMin, SMVUnitXY* pMvMax)
|
||||
{
|
||||
|
@ -2499,7 +2499,7 @@ static inline void SetNormalCodingFunc(SWelsFuncPtrList* pFuncList)
|
||||
|
||||
void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
||||
SDqLayer* pCurLayer = pCtx->pCurDqLayer;
|
||||
const bool kbBaseAvail = pCurLayer->bBaseLayerAvailableFlag;
|
||||
//const bool kbBaseAvail = pCurLayer->bBaseLayerAvailableFlag;
|
||||
const bool kbHighestSpatialLayer =
|
||||
(pCtx->pSvcParam->iSpatialLayerNum == (pCurLayer->sLayerInfo.sNalHeaderExt.uiDependencyId + 1));
|
||||
SWelsFuncPtrList* pFuncList = pCtx->pFuncList;
|
||||
|
@ -536,7 +536,7 @@ inline void MeRefineQuarPixel (SWelsFuncPtrList* pFunc, SWelsME* pMe, SMeRefineP
|
||||
int32_t iCurCost;
|
||||
uint8_t* pEncMb = pMe->pEncMb;
|
||||
uint8_t* pTmp = NULL;
|
||||
const uint8_t kuiPixel = pMe->uiPixel;
|
||||
const uint8_t kuiPixel = pMe->uiBlockSize;
|
||||
|
||||
pSampleAvg[kiAvgIndex] (pMeRefine->pQuarPixTmp, ME_REFINE_BUF_STRIDE, pParams->pSrcA[0], ME_REFINE_BUF_STRIDE,
|
||||
pParams->pSrcB[0], pParams->iStrideA, kiHeight);
|
||||
@ -603,7 +603,7 @@ void MeRefineFracPixel (sWelsEncCtx* pEncCtx, uint8_t* pMemPredInterMb, SWelsME*
|
||||
&& (pFunc->sSampleDealingFuncs.pfMdCost == pFunc->sSampleDealingFuncs.pfSampleSatd)) {
|
||||
iBestCost = pMe->uSadPredISatd.uiSatd + COST_MVD (pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY);
|
||||
} else {
|
||||
iBestCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel] (pEncData, kiStrideEnc, pRef, kiStrideRef) +
|
||||
iBestCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiBlockSize] (pEncData, kiStrideEnc, pRef, kiStrideRef) +
|
||||
COST_MVD (pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY);
|
||||
}
|
||||
|
||||
@ -614,7 +614,7 @@ void MeRefineFracPixel (sWelsEncCtx* pEncCtx, uint8_t* pMemPredInterMb, SWelsME*
|
||||
|
||||
//step 1: get [iWidth][iHeight+1] half pixel from vertical filter
|
||||
//===========================(0, -2)==============================//
|
||||
iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel] (pEncData, kiStrideEnc, pMeRefine->pHalfPixV,
|
||||
iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiBlockSize] (pEncData, kiStrideEnc, pMeRefine->pHalfPixV,
|
||||
ME_REFINE_BUF_STRIDE) +
|
||||
COST_MVD (pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy - 2 - pMe->sMvp.iMvY);
|
||||
if (iCurCost < iBestCost) {
|
||||
@ -623,7 +623,7 @@ void MeRefineFracPixel (sWelsEncCtx* pEncCtx, uint8_t* pMemPredInterMb, SWelsME*
|
||||
pBestPredInter = pMeRefine->pHalfPixV;
|
||||
}
|
||||
//===========================(0, 2)==============================//
|
||||
iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel] (pEncData, kiStrideEnc,
|
||||
iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiBlockSize] (pEncData, kiStrideEnc,
|
||||
pMeRefine->pHalfPixV + ME_REFINE_BUF_STRIDE, ME_REFINE_BUF_STRIDE) +
|
||||
COST_MVD (pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy + 2 - pMe->sMvp.iMvY);
|
||||
if (iCurCost < iBestCost) {
|
||||
@ -636,7 +636,7 @@ void MeRefineFracPixel (sWelsEncCtx* pEncCtx, uint8_t* pMemPredInterMb, SWelsME*
|
||||
//step 2: get [iWidth][iHeight+1] half pixel from horizon filter
|
||||
|
||||
//===========================(-2, 0)==============================//
|
||||
iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel] (pEncData, kiStrideEnc, pMeRefine->pHalfPixH,
|
||||
iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiBlockSize] (pEncData, kiStrideEnc, pMeRefine->pHalfPixH,
|
||||
ME_REFINE_BUF_STRIDE) +
|
||||
COST_MVD (pMe->pMvdCost, iMvx - 2 - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY);
|
||||
if (iCurCost < iBestCost) {
|
||||
@ -645,7 +645,7 @@ void MeRefineFracPixel (sWelsEncCtx* pEncCtx, uint8_t* pMemPredInterMb, SWelsME*
|
||||
pBestPredInter = pMeRefine->pHalfPixH;
|
||||
}
|
||||
//===========================(2, 0)===============================//
|
||||
iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel] (pEncData, kiStrideEnc, pMeRefine->pHalfPixH + 1,
|
||||
iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiBlockSize] (pEncData, kiStrideEnc, pMeRefine->pHalfPixH + 1,
|
||||
ME_REFINE_BUF_STRIDE) +
|
||||
COST_MVD (pMe->pMvdCost, iMvx + 2 - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY);
|
||||
if (iCurCost < iBestCost) {
|
||||
|
@ -359,7 +359,7 @@ void WelsMdInterInit (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb, const i
|
||||
ST32 (&pCurMb->sP16x16Mv, 0);
|
||||
ST32 (&pCurLayer->pDecPic->sMvList[kiMbXY], 0);
|
||||
|
||||
SetMvWithinMvRange( kiMbWidth, kiMbHeight, kiMbX, kiMbY, CAMERA_STARTMV_RANGE, &(pSlice->sMvStartMin), &(pSlice->sMvStartMax));
|
||||
SetMvWithinIntegerMvRange( kiMbWidth, kiMbHeight, kiMbX, kiMbY, CAMERA_STARTMV_RANGE, &(pSlice->sMvStartMin), &(pSlice->sMvStartMax));
|
||||
}
|
||||
|
||||
int32_t WelsMdI16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SMbCache* pMbCache, int32_t iLambda) {
|
||||
@ -975,7 +975,7 @@ static inline void InitMe(const SWelsMD& sWelsMd, const int32_t iBlockSize, uint
|
||||
{
|
||||
sWelsMe.iCurMeBlockPixX = sWelsMd.iMbPixX;
|
||||
sWelsMe.iCurMeBlockPixY = sWelsMd.iMbPixY;
|
||||
sWelsMe.uiPixel = iBlockSize;
|
||||
sWelsMe.uiBlockSize = iBlockSize;
|
||||
sWelsMe.pMvdCost = sWelsMd.pMvdCost;
|
||||
|
||||
sWelsMe.pEncMb = pEnc;
|
||||
|
@ -81,7 +81,7 @@ void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void
|
||||
MeEndIntepelSearch(pMe);
|
||||
}
|
||||
|
||||
pFuncList->pfCalculateSatd( pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiPixel], pMe, iStrideEnc, iStrideRef );
|
||||
pFuncList->pfCalculateSatd( pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiBlockSize], pMe, iStrideEnc, iStrideRef );
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -96,7 +96,7 @@ void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void
|
||||
*/
|
||||
bool WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlice, int32_t iStrideEnc,
|
||||
int32_t iStrideRef) {
|
||||
PSampleSadSatdCostFunc pSad = pFuncList->sSampleDealingFuncs.pfSampleSad[pMe->uiPixel];
|
||||
PSampleSadSatdCostFunc pSad = pFuncList->sSampleDealingFuncs.pfSampleSad[pMe->uiBlockSize];
|
||||
const uint16_t* kpMvdCost = pMe->pMvdCost;
|
||||
uint8_t* const kpEncMb = pMe->pEncMb;
|
||||
int16_t iMvc0, iMvc1;
|
||||
@ -197,7 +197,7 @@ bool WelsMeSadCostSelect (int32_t* iSadCost, const uint16_t* kpMvdCost, int32_t*
|
||||
|
||||
void WelsMotionEstimateIterativeSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe, const int32_t kiStrideEnc,
|
||||
const int32_t kiStrideRef, uint8_t* pFref) {
|
||||
PSample4SadCostFunc pSad = pFuncList->sSampleDealingFuncs.pfSample4Sad[pMe->uiPixel];
|
||||
PSample4SadCostFunc pSad = pFuncList->sSampleDealingFuncs.pfSample4Sad[pMe->uiBlockSize];
|
||||
|
||||
uint8_t* const kpEncMb = pMe->pEncMb;
|
||||
const uint16_t* kpMvdCost = pMe->pMvdCost;
|
||||
@ -255,7 +255,7 @@ bool CheckDirectionalMv(PSampleSadSatdCostFunc pSad, void * vpMe,
|
||||
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
|
||||
if ( (BLOCK_16x16!=pMe->uiBlockSize) //scrolled_MV with P16x16 is checked SKIP checking function
|
||||
&& ( kiMvX | kiMvY ) //(0,0) checked in ordinary initial point checking
|
||||
&& CheckMvInRange( pMe->sDirectionalMv, ksMinMv, ksMaxMv ) )
|
||||
{
|
||||
@ -278,4 +278,70 @@ bool CheckDirectionalMvFalse(PSampleSadSatdCostFunc pSad, void * vpMe,
|
||||
return false;
|
||||
}
|
||||
|
||||
void LineFullSearch_c( PSampleSadSatdCostFunc pSad, void *vpMe,
|
||||
uint16_t* pMvdTable, const int32_t kiFixedMvd,
|
||||
const int32_t kiEncStride, const int32_t kiRefStride,
|
||||
const int32_t kiMinPos, const int32_t kiMaxPos,
|
||||
const bool bVerticalSearch )
|
||||
{
|
||||
SWelsME *pMe = static_cast<SWelsME *>(vpMe);
|
||||
const int32_t kiCurMeBlockPix = bVerticalSearch?pMe->iCurMeBlockPixY:pMe->iCurMeBlockPixX;
|
||||
const int32_t kiStride = bVerticalSearch?kiRefStride:1;
|
||||
uint8_t* pRef = &pMe->pColoRefMb[(kiMinPos - kiCurMeBlockPix)*kiStride];
|
||||
uint16_t* pMvdCost = &(pMvdTable[kiMinPos<<2]);
|
||||
uint32_t uiBestCost = 0xFFFFFFFF;
|
||||
int32_t iBestPos = 0;
|
||||
|
||||
for ( int32_t iTargetPos = kiMinPos; iTargetPos < kiMaxPos; ++ iTargetPos ) {
|
||||
uint8_t* const kpEncMb = pMe->pEncMb;
|
||||
uint32_t uiSadCost = pSad( kpEncMb, kiEncStride, pRef, kiRefStride ) + (kiFixedMvd + *pMvdCost);
|
||||
if (uiSadCost < uiBestCost) {
|
||||
uiBestCost = uiSadCost;
|
||||
iBestPos = iTargetPos;
|
||||
}
|
||||
pRef += kiStride;
|
||||
pMvdCost+=4;
|
||||
}
|
||||
|
||||
if (uiBestCost < pMe->uiSadCost) {
|
||||
SMVUnitXY sBestMv;
|
||||
sBestMv.iMvX = bVerticalSearch?0:(iBestPos - kiCurMeBlockPix);
|
||||
sBestMv.iMvY = bVerticalSearch?(iBestPos - kiCurMeBlockPix):0;
|
||||
UpdateMeResults( sBestMv, uiBestCost, &pMe->pColoRefMb[sBestMv.iMvY*kiStride], pMe );
|
||||
}
|
||||
}
|
||||
|
||||
void WelsMotionCrossSearch(SWelsFuncPtrList *pFuncList, SDqLayer* pCurLayer, SWelsME * pMe,
|
||||
const SSlice* pSlice)
|
||||
{
|
||||
//TODO:
|
||||
//PMOTION_VERFULL_SEARCH VerticalFullSearchFunc = pFuncList->VerticalFullSearch_c;
|
||||
//PMOTION_HORFULL_SEARCH HorizontalFullSearchFunc = pFuncList->HorizontalFullSearch_c;
|
||||
const int32_t kiEncStride = pCurLayer->iEncStride[0];
|
||||
const int32_t kiRefStride = pCurLayer->pRefPic->iLineSize[0];
|
||||
|
||||
const int32_t iCurMeBlockPixX = pMe->iCurMeBlockPixX;
|
||||
const int32_t iCurMeBlockQpelPixX = ((iCurMeBlockPixX)<<2);
|
||||
const int32_t iCurMeBlockPixY = pMe->iCurMeBlockPixY;
|
||||
const int32_t iCurMeBlockQpelPixY = ((iCurMeBlockPixY)<<2);
|
||||
uint16_t* pMvdCostX = pMe->pMvdCost - iCurMeBlockQpelPixX - pMe->sMvp.iMvX;//do the offset here instead of in the search
|
||||
uint16_t* pMvdCostY = pMe->pMvdCost - iCurMeBlockQpelPixY - pMe->sMvp.iMvY;//do the offset here instead of in the search
|
||||
|
||||
//vertical search
|
||||
LineFullSearch_c( pFuncList->sSampleDealingFuncs.pfSampleSad[pMe->uiBlockSize], pMe,
|
||||
pMvdCostY, pMvdCostX[ iCurMeBlockQpelPixX ],
|
||||
kiEncStride, kiRefStride,
|
||||
iCurMeBlockPixY + pSlice->sMvStartMin.iMvY,
|
||||
iCurMeBlockPixY + pSlice->sMvStartMax.iMvY, true );
|
||||
|
||||
//horizontal search
|
||||
if (pMe->uiSadCost >= pMe->uiSadCostThreshold) {
|
||||
LineFullSearch_c( pFuncList->sSampleDealingFuncs.pfSampleSad[pMe->uiBlockSize], pMe,
|
||||
pMvdCostX, pMvdCostY[ iCurMeBlockQpelPixY ],
|
||||
kiEncStride, kiRefStride,
|
||||
iCurMeBlockPixX + pSlice->sMvStartMin.iMvX,
|
||||
iCurMeBlockPixX + pSlice->sMvStartMax.iMvX,
|
||||
false );
|
||||
}
|
||||
}
|
||||
} // namespace WelsSVCEnc
|
||||
|
@ -104,13 +104,13 @@ TEST_F(MotionEstimateTest, TestDiamondSearch)
|
||||
CopyTargetBlock( m_pSrcBlock, 16, sTargetMv, m_iWidth, pRefPicCenter);
|
||||
|
||||
//clean the sMe status
|
||||
sMe.uiPixel = rand()%5;
|
||||
sMe.uiBlockSize = rand()%5;
|
||||
sMe.pEncMb = m_pSrcBlock;
|
||||
sMe.pRefMb = pRefPicCenter;
|
||||
sMe.sMv.iMvX = sMe.sMv.iMvY = 0;
|
||||
sMe.uiSadCost = sMe.uiSatdCost = kiMaxBlock16Sad;
|
||||
WelsMotionEstimateIterativeSearch (&sFuncList, &sMe, m_iMaxSearchBlock,
|
||||
m_iWidth, pRefPicCenter);
|
||||
m_iWidth, pRefPicCenter);
|
||||
|
||||
//the last selection may be affected by MVDcost, that is when (0,0) will be better
|
||||
//when comparing (1,1) and (1,0), due to the difference between MVD cost, it is possible that (1,0) is selected while the best match is (1,1)
|
||||
@ -123,3 +123,129 @@ TEST_F(MotionEstimateTest, TestDiamondSearch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_F(MotionEstimateTest, TestVerticalSearch)
|
||||
{
|
||||
const int32_t kiMaxBlock16Sad = 72000;//a rough number
|
||||
SWelsFuncPtrList sFuncList;
|
||||
SWelsME sMe;
|
||||
|
||||
srand((uint32_t)time(NULL));
|
||||
const uint8_t kuiQp = rand()%52;
|
||||
InitMe(kuiQp, 648, m_uiMvdTableSize, m_pMvdCostTable, &sMe);
|
||||
|
||||
SMVUnitXY sTargetMv;
|
||||
WelsInitSampleSadFunc( &sFuncList, 0 );//test c functions
|
||||
|
||||
uint8_t *pRefPicCenter = m_pRefPic+(m_iHeight/2)*m_iWidth+(m_iWidth/2);
|
||||
sMe.iCurMeBlockPixX = (m_iWidth/2);
|
||||
sMe.iCurMeBlockPixY = (m_iHeight/2);
|
||||
|
||||
bool bDataGeneratorSucceed = false;
|
||||
bool bFoundMatch = false;
|
||||
int32_t iTryTimes=100;
|
||||
|
||||
sTargetMv.iMvX = 0;
|
||||
sTargetMv.iMvY = WELS_MAX(INTPEL_NEEDED_MARGIN, rand()%m_iHeight-INTPEL_NEEDED_MARGIN);
|
||||
bDataGeneratorSucceed = false;
|
||||
bFoundMatch = false;
|
||||
while (!bFoundMatch && (iTryTimes--)>0) {
|
||||
if (!YUVPixelDataGenerator( m_pRefPic, m_iWidth, m_iHeight, m_iWidth ))
|
||||
continue;
|
||||
|
||||
bDataGeneratorSucceed = true;
|
||||
CopyTargetBlock( m_pSrcBlock, 16, sTargetMv, m_iWidth, pRefPicCenter);
|
||||
|
||||
//clean the sMe status
|
||||
sMe.uiBlockSize = rand()%5;
|
||||
sMe.pEncMb = m_pSrcBlock;
|
||||
sMe.pRefMb = pRefPicCenter;
|
||||
sMe.pColoRefMb = pRefPicCenter;
|
||||
sMe.sMv.iMvX = sMe.sMv.iMvY = 0;
|
||||
sMe.uiSadCost = sMe.uiSatdCost = kiMaxBlock16Sad;
|
||||
const int32_t iCurMeBlockPixX = sMe.iCurMeBlockPixX;
|
||||
const int32_t iCurMeBlockQpelPixX = ((iCurMeBlockPixX)<<2);
|
||||
const int32_t iCurMeBlockPixY = sMe.iCurMeBlockPixY;
|
||||
const int32_t iCurMeBlockQpelPixY = ((iCurMeBlockPixY)<<2);
|
||||
uint16_t* pMvdCostX = sMe.pMvdCost - iCurMeBlockQpelPixX - sMe.sMvp.iMvX; //do the offset here
|
||||
uint16_t* pMvdCostY = sMe.pMvdCost - iCurMeBlockQpelPixY - sMe.sMvp.iMvY;
|
||||
LineFullSearch_c ( sFuncList.sSampleDealingFuncs.pfSampleSad[sMe.uiBlockSize], &sMe,
|
||||
pMvdCostY, pMvdCostX[ iCurMeBlockQpelPixX ],
|
||||
m_iMaxSearchBlock, m_iWidth,
|
||||
INTPEL_NEEDED_MARGIN,
|
||||
m_iHeight-INTPEL_NEEDED_MARGIN, true );
|
||||
|
||||
//the last selection may be affected by MVDcost, that is when smaller MvY will be better
|
||||
bFoundMatch = (sMe.sMv.iMvX==0
|
||||
&&(sMe.sMv.iMvY==sTargetMv.iMvY||abs(sMe.sMv.iMvY)<abs(sTargetMv.iMvY)));
|
||||
//printf("TestVerticalSearch Target: %d,%d\n", sTargetMv.iMvX, sTargetMv.iMvY);
|
||||
}
|
||||
if (bDataGeneratorSucceed) {
|
||||
//if DataGenerator never succeed, there is no meaning to check iTryTimes
|
||||
ASSERT_TRUE(iTryTimes > 0);
|
||||
//it is possible that ref at differnt position is identical, but that should be under a low probability
|
||||
}
|
||||
}
|
||||
TEST_F(MotionEstimateTest, TestHorizontalSearch)
|
||||
{
|
||||
const int32_t kiMaxBlock16Sad = 72000;//a rough number
|
||||
SWelsFuncPtrList sFuncList;
|
||||
SWelsME sMe;
|
||||
|
||||
srand((uint32_t)time(NULL));
|
||||
const uint8_t kuiQp = rand()%52;
|
||||
InitMe(kuiQp, 648, m_uiMvdTableSize, m_pMvdCostTable, &sMe);
|
||||
|
||||
SMVUnitXY sTargetMv;
|
||||
WelsInitSampleSadFunc( &sFuncList, 0 );//test c functions
|
||||
|
||||
uint8_t *pRefPicCenter = m_pRefPic+(m_iHeight/2)*m_iWidth+(m_iWidth/2);
|
||||
sMe.iCurMeBlockPixX = (m_iWidth/2);
|
||||
sMe.iCurMeBlockPixY = (m_iHeight/2);
|
||||
|
||||
bool bDataGeneratorSucceed = false;
|
||||
bool bFoundMatch = false;
|
||||
int32_t iTryTimes=100;
|
||||
|
||||
sTargetMv.iMvX = WELS_MAX(INTPEL_NEEDED_MARGIN, rand()%m_iWidth-INTPEL_NEEDED_MARGIN);
|
||||
sTargetMv.iMvY = 0;
|
||||
bDataGeneratorSucceed = false;
|
||||
bFoundMatch = false;
|
||||
while (!bFoundMatch && (iTryTimes--)>0) {
|
||||
if (!YUVPixelDataGenerator( m_pRefPic, m_iWidth, m_iHeight, m_iWidth ))
|
||||
continue;
|
||||
|
||||
bDataGeneratorSucceed = true;
|
||||
CopyTargetBlock( m_pSrcBlock, 16, sTargetMv, m_iWidth, pRefPicCenter);
|
||||
|
||||
//clean the sMe status
|
||||
sMe.uiBlockSize = rand()%5;
|
||||
sMe.pEncMb = m_pSrcBlock;
|
||||
sMe.pRefMb = pRefPicCenter;
|
||||
sMe.pColoRefMb = pRefPicCenter;
|
||||
sMe.sMv.iMvX = sMe.sMv.iMvY = 0;
|
||||
sMe.uiSadCost = sMe.uiSatdCost = kiMaxBlock16Sad;
|
||||
const int32_t iCurMeBlockPixX = sMe.iCurMeBlockPixX;
|
||||
const int32_t iCurMeBlockQpelPixX = ((iCurMeBlockPixX)<<2);
|
||||
const int32_t iCurMeBlockPixY = sMe.iCurMeBlockPixY;
|
||||
const int32_t iCurMeBlockQpelPixY = ((iCurMeBlockPixY)<<2);
|
||||
uint16_t* pMvdCostX = sMe.pMvdCost - iCurMeBlockQpelPixX - sMe.sMvp.iMvX; //do the offset here
|
||||
uint16_t* pMvdCostY = sMe.pMvdCost - iCurMeBlockQpelPixY - sMe.sMvp.iMvY;
|
||||
LineFullSearch_c ( sFuncList.sSampleDealingFuncs.pfSampleSad[sMe.uiBlockSize], &sMe,
|
||||
pMvdCostX, pMvdCostY[ iCurMeBlockQpelPixY ],
|
||||
m_iMaxSearchBlock, m_iWidth,
|
||||
INTPEL_NEEDED_MARGIN,
|
||||
m_iWidth-INTPEL_NEEDED_MARGIN, false );
|
||||
|
||||
//the last selection may be affected by MVDcost, that is when smaller MvY will be better
|
||||
bFoundMatch = (sMe.sMv.iMvY==0
|
||||
&&(sMe.sMv.iMvX==sTargetMv.iMvX||abs(sMe.sMv.iMvX)<abs(sTargetMv.iMvX)));
|
||||
//printf("TestHorizontalSearch Target: %d,%d\n", sTargetMv.iMvX, sTargetMv.iMvY);
|
||||
}
|
||||
if (bDataGeneratorSucceed) {
|
||||
//if DataGenerator never succeed, there is no meaning to check iTryTimes
|
||||
ASSERT_TRUE(iTryTimes > 0);
|
||||
//it is possible that ref at differnt position is identical, but that should be under a low probability
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user