History

Merge pull request #616 from sijchen/fme_merge81

[Encoder ME] add function pointer for search methods

Licai Guo committed 12 years ago

Commit c12edef2 parents ea5b6b4 f6952277 files · +36 −32Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t