From 92e5489dd3da00771c7be151ca3e33c7d088ced0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 5 May 2014 16:11:19 +0300 Subject: [PATCH] Avoid duplicating code in the MotionEstimate test All the tests of the line search (unoptimized and optimized) use the exact same copypasted structure. Instead factorize this into a test function which uses the provided function. --- test/encoder/EncUT_MotionEstimate.cpp | 219 ++++---------------------- 1 file changed, 33 insertions(+), 186 deletions(-) diff --git a/test/encoder/EncUT_MotionEstimate.cpp b/test/encoder/EncUT_MotionEstimate.cpp index 0f36c1b0..9edfbc43 100644 --- a/test/encoder/EncUT_MotionEstimate.cpp +++ b/test/encoder/EncUT_MotionEstimate.cpp @@ -67,6 +67,7 @@ public: m_pMvdCostTable=new uint16_t[52*m_uiMvdTableSize]; ASSERT_TRUE( NULL != m_pMvdCostTable ); } + void DoLineTest(PLineFullSearchFunc func, bool horizontal); virtual void TearDown() { delete [] m_pMvdCostTable; pMa->WelsFree( m_pRefData, "RefPic"); @@ -139,7 +140,7 @@ TEST_F(MotionEstimateTest, TestDiamondSearch) { } -TEST_F(MotionEstimateTest, TestVerticalSearch) { +void MotionEstimateTest::DoLineTest(PLineFullSearchFunc func, bool vertical) { const int32_t kiMaxBlock16Sad = 72000;//a rough number SWelsFuncPtrList sFuncList; SWelsME sMe; @@ -150,6 +151,7 @@ TEST_F(MotionEstimateTest, TestVerticalSearch) { SMVUnitXY sTargetMv; WelsInitSampleSadFunc( &sFuncList, 0 );//test c functions + WelsInitMeFunc(&sFuncList, WelsCPUFeatureDetect(NULL), 1); uint8_t *pRefPicCenter = m_pRefData+(m_iHeight/2)*m_iWidth+(m_iWidth/2); sMe.iCurMeBlockPixX = (m_iWidth/2); @@ -159,8 +161,13 @@ TEST_F(MotionEstimateTest, TestVerticalSearch) { bool bFoundMatch = false; int32_t iTryTimes=100; - sTargetMv.iMvX = 0; - sTargetMv.iMvY = -sMe.iCurMeBlockPixY + INTPEL_NEEDED_MARGIN + rand()%(m_iHeight - 16 - 2*INTPEL_NEEDED_MARGIN); + if (vertical) { + sTargetMv.iMvX = 0; + sTargetMv.iMvY = -sMe.iCurMeBlockPixY + INTPEL_NEEDED_MARGIN + rand()%(m_iHeight - 16 - 2*INTPEL_NEEDED_MARGIN); + } else { + sTargetMv.iMvX = -sMe.iCurMeBlockPixX + INTPEL_NEEDED_MARGIN + rand()%(m_iWidth - 16 - 2*INTPEL_NEEDED_MARGIN); + sTargetMv.iMvY = 0; + } bDataGeneratorSucceed = false; bFoundMatch = false; while (!bFoundMatch && (iTryTimes--)>0) { @@ -183,16 +190,24 @@ TEST_F(MotionEstimateTest, TestVerticalSearch) { 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, &sMe, - pMvdCostY, pMvdCostX[ iCurMeBlockQpelPixX ], - m_iMaxSearchBlock, m_iWidth, - INTPEL_NEEDED_MARGIN, - m_iHeight-INTPEL_NEEDED_MARGIN-16, true ); + uint16_t* pMvdCost = vertical ? pMvdCostY : pMvdCostX; + int iSize = vertical ? m_iHeight : m_iWidth; + int iFixedMvd = vertical ? pMvdCostX[ iCurMeBlockQpelPixX ] : pMvdCostY[ iCurMeBlockQpelPixY ]; + func ( &sFuncList, &sMe, + pMvdCost, iFixedMvd, + m_iMaxSearchBlock, m_iWidth, + INTPEL_NEEDED_MARGIN, + iSize-INTPEL_NEEDED_MARGIN-16, vertical ); //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)0) { - if (!YUVPixelDataGenerator( m_pRefData, 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, &sMe, - pMvdCostX, pMvdCostY[ iCurMeBlockQpelPixY ], - m_iMaxSearchBlock, m_iWidth, - INTPEL_NEEDED_MARGIN, - m_iWidth-INTPEL_NEEDED_MARGIN-16, 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) 0); - //it is possible that ref at differnt position is identical, but that should be under a low probability - } + DoLineTest(LineFullSearch_c, false); } #ifdef X86_ASM TEST_F(MotionEstimateTest, TestVerticalSearch_SSE41) { - 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); int32_t iTmp = 1; uint32_t uiCPUFlags = WelsCPUFeatureDetect( &iTmp); if ((uiCPUFlags & WELS_CPU_SSE41) == 0) return ; - SMVUnitXY sTargetMv; - WelsInitSampleSadFunc( &sFuncList, 0 );//test c functions - WelsInitMeFunc(&sFuncList, WELS_CPU_SSE41, 1); - - uint8_t *pRefPicCenter = m_pRefData+(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 = -sMe.iCurMeBlockPixY + INTPEL_NEEDED_MARGIN + rand()%(m_iHeight - 16 - 2*INTPEL_NEEDED_MARGIN); - bDataGeneratorSucceed = false; - bFoundMatch = false; - while (!bFoundMatch && (iTryTimes--)>0) { - if (!YUVPixelDataGenerator( m_pRefData, 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; - VerticalFullSearchUsingSSE41 ( &sFuncList, &sMe, - pMvdCostY, pMvdCostX[ iCurMeBlockQpelPixX ], - m_iMaxSearchBlock, m_iWidth, - INTPEL_NEEDED_MARGIN, - m_iHeight-INTPEL_NEEDED_MARGIN-16, 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) 0); - //it is possible that ref at differnt position is identical, but that should be under a low probability - } + DoLineTest(VerticalFullSearchUsingSSE41, true); } TEST_F(MotionEstimateTest, TestHorizontalSearch_SSE41) { - 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); int32_t iTmp = 1; uint32_t uiCPUFlags = WelsCPUFeatureDetect( &iTmp); if ((uiCPUFlags & WELS_CPU_SSE41) == 0) return ; - SMVUnitXY sTargetMv; - WelsInitSampleSadFunc( &sFuncList, 0 );//test c functions - WelsInitMeFunc(&sFuncList, WELS_CPU_SSE41, 1); - uint8_t *pRefPicCenter = m_pRefData+(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 = -sMe.iCurMeBlockPixX + INTPEL_NEEDED_MARGIN + rand()%(m_iWidth - 16 - 2*INTPEL_NEEDED_MARGIN); - sTargetMv.iMvY = 0; - bDataGeneratorSucceed = false; - bFoundMatch = false; - while (!bFoundMatch && (iTryTimes--)>0) { - if (!YUVPixelDataGenerator( m_pRefData, m_iWidth, m_iHeight, m_iWidth )) - continue; - bDataGeneratorSucceed = true; - CopyTargetBlock( m_pSrcBlock, m_iMaxSearchBlock, sTargetMv, m_iWidth, pRefPicCenter ); - - //clean 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; - HorizontalFullSearchUsingSSE41 ( &sFuncList, &sMe, - pMvdCostX, pMvdCostY[ iCurMeBlockQpelPixY ], - m_iMaxSearchBlock, m_iWidth, - INTPEL_NEEDED_MARGIN, - m_iWidth-INTPEL_NEEDED_MARGIN-16, 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) 0); - //it is possible that ref at differnt position is identical, but that should be under a low probability - } + DoLineTest(HorizontalFullSearchUsingSSE41, false); } #endif