[Encoder ME] add function pointer for search methods
Unified · Split
| @@ -179,8 +179,7 @@ bool WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe, · 178 unmodified lines | ||
| 179 | 179 | * |
| 180 | 180 | * \return NONE |
| 181 | 181 | */ |
| 182 | −void WelsMotionEstimateIterativeSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe, const int32_t kiStrideEnc, | |
| 183 | − const int32_t kiStrideRef, uint8_t* pRef); | |
| 182 | +void WelsDiamondSearch (SWelsFuncPtrList* pFuncList, void* pLpme, void* pLpslice, const int32_t kiEncStride, const int32_t kiRefStride); | |
| 184 | 183 | |
| 185 | 184 | bool WelsMeSadCostSelect (int32_t* pSadCost, const uint16_t* kpMvdCost, int32_t* pBestCost, const int32_t kiDx, |
| 186 | 185 | const int32_t kiDy, int32_t* pIx, int32_t* pIy); |
| @@ -43,6 +43,7 @@ · 42 unmodified lines | ||
| 43 | 43 | #include "svc_enc_frame.h" |
| 44 | 44 | #include "expand_pic.h" |
| 45 | 45 | #include "rc.h" |
| 46 | +#include "IWelsVP.h" | |
| 46 | 47 | |
| 47 | 48 | namespace WelsSVCEnc { |
| 48 | 49 | |
| @@ -135,7 +136,8 @@ typedef int32_t (*PIntraPred8x8Combined3Func) (uint8_t*, int32_t, uint8_t*, int3 · 86 unmodified lines | ||
| 135 | 136 | |
| 136 | 137 | typedef void (*PMotionSearchFunc) (SWelsFuncPtrList* pFuncList, void* pCurDqLayer, void* pMe, |
| 137 | 138 | void* pSlice); |
| 138 | −typedef void (*PCalculateSatdFunc) ( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride ); | |
| 139 | +typedef void (*PSearchMethodFunc) (SWelsFuncPtrList* pFuncList, void* pMe, void* pSlice, const int32_t kiEncStride, const int32_t kiRefStride); | |
| 140 | +typedef void (*PCalculateSatdFunc) ( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride); | |
| 139 | 141 | typedef bool (*PCheckDirectionalMv) (PSampleSadSatdCostFunc pSad, void * vpMe, |
| 140 | 142 | const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride, |
| 141 | 143 | int32_t& iBestSadCost); |
| @@ -198,7 +200,8 @@ struct TagWelsFuncPointerList { · 56 unmodified lines | ||
| 198 | 200 | PGetIntraPredFunc pfGetChromaPred[C_PRED_A]; |
| 199 | 201 | |
| 200 | 202 | PMotionSearchFunc |
| 201 | − pfMotionSearch; //svc_encode_slice.c svc_mode_decision.c svc_enhance_layer_md.c svc_base_layer_md.c | |
| 203 | + pfMotionSearch[BLOCK_STATIC_IDC_ALL]; //svc_encode_slice.c svc_mode_decision.c svc_enhance_layer_md.c svc_base_layer_md.c | |
| 204 | + PSearchMethodFunc pfSearchMethod[BLOCK_SIZE_ALL]; | |
| 202 | 205 | PCalculateSatdFunc pfCalculateSatd; |
| 203 | 206 | PCheckDirectionalMv pfCheckDirectionalMv; |
| 204 | 207 | PLineFullSearchFunc pfLineFullSearch; |
| @@ -2366,7 +2366,12 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) { · 2365 unmodified lines | ||
| 2366 | 2366 | } |
| 2367 | 2367 | |
| 2368 | 2368 | if (P_SLICE == pCtx->eSliceType) { |
| 2369 | − pFuncList->pfMotionSearch = WelsMotionEstimateSearch; | |
| 2369 | + pFuncList->pfMotionSearch[0] = WelsMotionEstimateSearch; | |
| 2370 | + pFuncList->pfSearchMethod[BLOCK_16x16] = | |
| 2371 | + pFuncList->pfSearchMethod[BLOCK_16x8] = | |
| 2372 | + pFuncList->pfSearchMethod[BLOCK_8x16] = | |
| 2373 | + pFuncList->pfSearchMethod[BLOCK_8x8] = | |
| 2374 | + pFuncList->pfSearchMethod[BLOCK_4x4] = WelsDiamondSearch; | |
| 2370 | 2375 | pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode; |
| 2371 | 2376 | pFuncList->sSampleDealingFuncs.pfMeCost = pCtx->pFuncList->sSampleDealingFuncs.pfSampleSatd; |
| 2372 | 2377 | if (kbHighestSpatialLayer) { |
| @@ -1018,8 +1018,7 @@ int32_t WelsMdP16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWe · 1017 unmodified lines | ||
| 1018 | 1018 | } |
| 1019 | 1019 | |
| 1020 | 1020 | PredMv (&pMbCache->sMvComponents, 0, 4, 0, & (pMe16x16->sMvp)); |
| 1021 | − pFunc->pfMotionSearch (pFunc, pCurLayer, pMe16x16, pSlice); | |
| 1022 | −// update_p16x16_motion2cache(pMbCache, pWelsMd->uiRef, &(pMe16x16->mv)); | |
| 1021 | + pFunc->pfMotionSearch[0] (pFunc, pCurLayer, pMe16x16, pSlice); | |
| 1023 | 1022 | |
| 1024 | 1023 | pCurMb->sP16x16Mv = pMe16x16->sMv; |
| 1025 | 1024 | pCurLayer->pDecPic->sMvList[pCurMb->iMbXY] = pMe16x16->sMv; |
| @@ -1048,7 +1047,7 @@ int32_t WelsMdP16x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pW · 22 unmodified lines | ||
| 1048 | 1047 | pSlice->uiMvcNum = 1; |
| 1049 | 1048 | |
| 1050 | 1049 | PredInter16x8Mv (pMbCache, i << 3, 0, & (sMe16x8->sMvp)); |
| 1051 | − pFunc->pfMotionSearch (pFunc, pCurDqLayer, sMe16x8, pSlice); | |
| 1050 | + pFunc->pfMotionSearch[0] (pFunc, pCurDqLayer, sMe16x8, pSlice); | |
| 1052 | 1051 | UpdateP16x8Motion2Cache (pMbCache, i << 3, pWelsMd->uiRef, & (sMe16x8->sMv)); |
| 1053 | 1052 | iCostP16x8 += sMe16x8->uiSatdCost; |
| 1054 | 1053 | ++i; |
| @@ -1075,10 +1074,9 @@ int32_t WelsMdP8x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWel · 20 unmodified lines | ||
| 1075 | 1074 | pSlice->uiMvcNum = 1; |
| 1076 | 1075 | |
| 1077 | 1076 | PredInter8x16Mv (pMbCache, i << 2, 0, & (sMe8x16->sMvp)); |
| 1078 | − pFunc->pfMotionSearch (pFunc, pCurLayer, sMe8x16, pSlice); | |
| 1077 | + pFunc->pfMotionSearch[0] (pFunc, pCurLayer, sMe8x16, pSlice); | |
| 1079 | 1078 | UpdateP8x16Motion2Cache (pMbCache, i << 2, pWelsMd->uiRef, & (sMe8x16->sMv)); |
| 1080 | 1079 | iCostP8x16 += sMe8x16->uiSatdCost; |
| 1081 | −// sMe8x16++; | |
| 1082 | 1080 | ++i; |
| 1083 | 1081 | } while (i < 2); |
| 1084 | 1082 | return iCostP8x16; |
| @@ -1113,7 +1111,7 @@ int32_t WelsMdP8x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWe · 28 unmodified lines | ||
| 1113 | 1111 | pSlice->uiMvcNum = 1; |
| 1114 | 1112 | |
| 1115 | 1113 | PredMv (&pMbCache->sMvComponents, i << 2, 2, pWelsMd->uiRef, & (sMe8x8->sMvp)); |
| 1116 | − pFunc->pfMotionSearch (pFunc, pCurDqLayer, sMe8x8, pSlice); | |
| 1114 | + pFunc->pfMotionSearch[0] (pFunc, pCurDqLayer, sMe8x8, pSlice); | |
| 1117 | 1115 | UpdateP8x8Motion2Cache (pMbCache, i << 2, pWelsMd->uiRef, & (sMe8x8->sMv)); |
| 1118 | 1116 | iCostP8x8 += sMe8x8->uiSatdCost; |
| 1119 | 1117 | // sMe8x8++; |
| @@ -83,16 +83,16 @@ void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void · 82 unmodified lines | ||
| 83 | 83 | SDqLayer* pCurDqLayer = (SDqLayer*)pLplayer; |
| 84 | 84 | SWelsME* pMe = (SWelsME*)pLpme; |
| 85 | 85 | SSlice* pSlice = (SSlice*)pLpslice; |
| 86 | − int32_t iStrideEnc = pCurDqLayer->iEncStride[0]; | |
| 87 | − int32_t iStrideRef = pCurDqLayer->pRefPic->iLineSize[0]; | |
| 86 | + const int32_t kiStrideEnc = pCurDqLayer->iEncStride[0]; | |
| 87 | + const int32_t kiStrideRef = pCurDqLayer->pRefPic->iLineSize[0]; | |
| 88 | 88 | |
| 89 | 89 | // Step 1: Initial point prediction |
| 90 | − if ( !WelsMotionEstimateInitialPoint (pFuncList, pMe, pSlice, iStrideEnc, iStrideRef) ) { | |
| 91 | − WelsMotionEstimateIterativeSearch (pFuncList, pMe, iStrideEnc, iStrideRef, pMe->pRefMb); | |
| 90 | + if ( !WelsMotionEstimateInitialPoint (pFuncList, pMe, pSlice, kiStrideEnc, kiStrideRef) ) { | |
| 91 | + pFuncList->pfSearchMethod[pMe->uiBlockSize] (pFuncList, pMe, pSlice, kiStrideEnc, kiStrideRef); | |
| 92 | 92 | MeEndIntepelSearch(pMe); |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | − pFuncList->pfCalculateSatd( pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiBlockSize], pMe, iStrideEnc, iStrideRef ); | |
| 95 | + pFuncList->pfCalculateSatd( pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiBlockSize], pMe, kiStrideEnc, kiStrideRef ); | |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | 98 | /*! |
| @@ -219,10 +219,12 @@ bool WelsMeSadCostSelect (int32_t* iSadCost, const uint16_t* kpMvdCost, int32_t* · 120 unmodified lines | ||
| 219 | 219 | return (*pBestCost == iInputSadCost); |
| 220 | 220 | } |
| 221 | 221 | |
| 222 | −void WelsMotionEstimateIterativeSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe, const int32_t kiStrideEnc, | |
| 223 | − const int32_t kiStrideRef, uint8_t* pFref) { | |
| 222 | +void WelsDiamondSearch (SWelsFuncPtrList* pFuncList, void* pLpme, void* pLpslice, | |
| 223 | + const int32_t kiStrideEnc, const int32_t kiStrideRef) { | |
| 224 | + SWelsME* pMe = (SWelsME*)pLpme; | |
| 224 | 225 | PSample4SadCostFunc pSad = pFuncList->sSampleDealingFuncs.pfSample4Sad[pMe->uiBlockSize]; |
| 225 | 226 | |
| 227 | + uint8_t* pFref = pMe->pRefMb; | |
| 226 | 228 | uint8_t* const kpEncMb = pMe->pEncMb; |
| 227 | 229 | const uint16_t* kpMvdCost = pMe->pMvdCost; |
| 228 | 230 | |
| @@ -334,12 +336,10 @@ void LineFullSearch_c( void *pFunc, void *vpMe, · 105 unmodified lines | ||
| 334 | 336 | } |
| 335 | 337 | } |
| 336 | 338 | |
| 337 | −void WelsMotionCrossSearch(SWelsFuncPtrList *pFuncList, SDqLayer* pCurLayer, SWelsME * pMe, | |
| 338 | − const SSlice* pSlice) { | |
| 339 | +void WelsMotionCrossSearch(SWelsFuncPtrList *pFuncList, SWelsME * pMe, | |
| 340 | + const SSlice* pSlice, const int32_t kiEncStride, const int32_t kiRefStride) { | |
| 339 | 341 | PLineFullSearchFunc pfVerticalFullSearchFunc = pFuncList->pfLineFullSearch; |
| 340 | 342 | PLineFullSearchFunc pfHorizontalFullSearchFunc = pFuncList->pfLineFullSearch; |
| 341 | − const int32_t kiEncStride = pCurLayer->iEncStride[0]; | |
| 342 | − const int32_t kiRefStride = pCurLayer->pRefPic->iLineSize[0]; | |
| 343 | 343 | |
| 344 | 344 | const int32_t iCurMeBlockPixX = pMe->iCurMeBlockPixX; |
| 345 | 345 | const int32_t iCurMeBlockQpelPixX = ((iCurMeBlockPixX)<<2); |
| @@ -564,28 +564,26 @@ void MotionEstimateFeatureFullSearch( SFeatureSearchIn &sFeatureSearchIn, · 218 unmodified lines | ||
| 564 | 564 | ///////////////////////// |
| 565 | 565 | // Search function options |
| 566 | 566 | ///////////////////////// |
| 567 | −void WelsDiamondCrossSearch(SWelsFuncPtrList *pFunc, void* vpLayer, void* vpMe, void* vpSlice) { | |
| 568 | − SDqLayer* pCurLayer = static_cast<SDqLayer *>(vpLayer); | |
| 567 | +void WelsDiamondCrossSearch(SWelsFuncPtrList *pFunc, void* vpMe, void* vpSlice, const int32_t kiEncStride, const int32_t kiRefStride) { | |
| 569 | 568 | SWelsME* pMe = static_cast<SWelsME *>(vpMe); |
| 570 | 569 | SSlice* pSlice = static_cast<SSlice *>(vpSlice); |
| 571 | 570 | |
| 572 | 571 | // Step 1: diamond search |
| 573 | − WelsMotionEstimateIterativeSearch(pFunc, pMe, pCurLayer->iEncStride[0], pCurLayer->pRefPic->iLineSize[0], pMe->pRefMb); | |
| 572 | + WelsDiamondSearch(pFunc, vpMe, vpSlice, kiEncStride, kiRefStride); | |
| 574 | 573 | |
| 575 | 574 | // Step 2: CROSS search |
| 576 | 575 | SScreenBlockFeatureStorage pRefBlockFeature; //TODO: use this structure from Ref |
| 577 | 576 | pMe->uiSadCostThreshold = pRefBlockFeature.uiSadCostThreshold[pMe->uiBlockSize]; |
| 578 | 577 | if (pMe->uiSadCost >= pMe->uiSadCostThreshold) { |
| 579 | − WelsMotionCrossSearch(pFunc, pCurLayer, pMe, pSlice); | |
| 578 | + WelsMotionCrossSearch(pFunc, pMe, pSlice, kiEncStride, kiRefStride); | |
| 580 | 579 | } |
| 581 | 580 | } |
| 582 | −void WelsDiamondCrossFeatureSearch(SWelsFuncPtrList *pFunc, void* vpLayer, void* vpMe, void* vpSlice) { | |
| 583 | − SDqLayer* pCurLayer = static_cast<SDqLayer *>(vpLayer); | |
| 581 | +void WelsDiamondCrossFeatureSearch(SWelsFuncPtrList *pFunc, void* vpMe, void* vpSlice, const int32_t kiEncStride, const int32_t kiRefStride) { | |
| 584 | 582 | SWelsME* pMe = static_cast<SWelsME *>(vpMe); |
| 585 | 583 | SSlice* pSlice = static_cast<SSlice *>(vpSlice); |
| 586 | 584 | |
| 587 | 585 | // Step 1: diamond search + cross |
| 588 | − WelsDiamondCrossSearch(pFunc, pCurLayer, pMe, pSlice); | |
| 586 | + WelsDiamondCrossSearch(pFunc, pMe, pSlice, kiEncStride, kiRefStride); | |
| 589 | 587 | |
| 590 | 588 | // Step 2: FeatureSearch |
| 591 | 589 | if (pMe->uiSadCost >= pMe->uiSadCostThreshold) { |
| @@ -595,7 +593,7 @@ void WelsDiamondCrossFeatureSearch(SWelsFuncPtrList *pFunc, void* vpLayer, void* · 3 unmodified lines | ||
| 595 | 593 | uint32_t uiMaxSearchPoint = INT_MAX;//TODO: change it according to computational-complexity setting |
| 596 | 594 | SFeatureSearchIn sFeatureSearchIn = {0}; |
| 597 | 595 | SetFeatureSearchIn(pFunc, *pMe, pSlice, &tmpScreenBlockFeatureStorage, |
| 598 | − pCurLayer->iEncStride[0], pCurLayer->pRefPic->iLineSize[0], | |
| 596 | + kiEncStride, kiRefStride, | |
| 599 | 597 | &sFeatureSearchIn); |
| 600 | 598 | MotionEstimateFeatureFullSearch( sFeatureSearchIn, uiMaxSearchPoint, pMe); |
| 601 | 599 | |
| @@ -148,6 +148,7 @@ typedef enum { · 147 unmodified lines | ||
| 148 | 148 | NO_STATIC, // motion block |
| 149 | 149 | COLLOCATED_STATIC, // collocated static block |
| 150 | 150 | SCROLLED_STATIC, // scrolled static block |
| 151 | + BLOCK_STATIC_IDC_ALL, | |
| 151 | 152 | } EStaticBlockIdc; |
| 152 | 153 | |
| 153 | 154 | typedef struct { |
| @@ -75,6 +75,7 @@ TEST_F(MotionEstimateTest, TestDiamondSearch) { · 74 unmodified lines | ||
| 75 | 75 | const int32_t kiMaxBlock16Sad = 72000;//a rough number |
| 76 | 76 | SWelsFuncPtrList sFuncList; |
| 77 | 77 | SWelsME sMe; |
| 78 | + SSlice sSlice; | |
| 78 | 79 | |
| 79 | 80 | srand((uint32_t)time(NULL)); |
| 80 | 81 | const uint8_t kuiQp = rand()%52; |
| @@ -106,8 +107,7 @@ TEST_F(MotionEstimateTest, TestDiamondSearch) { · 25 unmodified lines | ||
| 106 | 107 | sMe.pRefMb = pRefPicCenter; |
| 107 | 108 | sMe.sMv.iMvX = sMe.sMv.iMvY = 0; |
| 108 | 109 | sMe.uiSadCost = sMe.uiSatdCost = kiMaxBlock16Sad; |
| 109 | − WelsMotionEstimateIterativeSearch (&sFuncList, &sMe, m_iMaxSearchBlock, | |
| 110 | − m_iWidth, pRefPicCenter); | |
| 110 | + WelsDiamondSearch (&sFuncList, &sMe, &sSlice, m_iMaxSearchBlock, m_iWidth); | |
| 111 | 111 | |
| 112 | 112 | //the last selection may be affected by MVDcost, that is when (0,0) will be better |
| 113 | 113 | //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) |