From 2fe99d688bea0d38d2a69fd775a6f9b09e1066d4 Mon Sep 17 00:00:00 2001 From: sijchen Date: Fri, 14 Mar 2014 16:40:02 +0800 Subject: [PATCH] add basic me test --- Makefile | 5 +- test/DataGenerator.cpp | 65 ++++++++++++++++++ test/EncUT_MemoryAlloc.cpp | 8 +-- test/EncUT_MotionEstimate.cpp | 125 ++++++++++++++++++++++++++++++++++ test/targets.mk | 4 +- test/utils/DataGenerator.h | 15 ++++ 6 files changed, 215 insertions(+), 7 deletions(-) create mode 100644 test/DataGenerator.cpp create mode 100644 test/EncUT_MotionEstimate.cpp create mode 100644 test/utils/DataGenerator.h diff --git a/Makefile b/Makefile index 7a58e7c9..34bff456 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,10 @@ GTEST_INCLUDES += \ -Igtest/include CODEC_UNITTEST_INCLUDES += \ - -Igtest/include + -Igtest/include \ + -Icodec/processing/interface \ + -Icodec/common \ + -Icodec/encoder/core/inc H264DEC_INCLUDES = $(DECODER_INCLUDES) -Icodec/console/dec/inc H264DEC_LDFLAGS = -L. $(call LINK_LIB,decoder) $(call LINK_LIB,common) diff --git a/test/DataGenerator.cpp b/test/DataGenerator.cpp new file mode 100644 index 00000000..c8a28e89 --- /dev/null +++ b/test/DataGenerator.cpp @@ -0,0 +1,65 @@ +#include //memset/memcpy +#include "utils/DataGenerator.h" +#include "utils/BufferedData.h" +#include "utils/FileInputStream.h" + +using namespace std; + + +bool YUVPixelDataGenerator( uint8_t* pPointer, int32_t iWidth, int32_t iHeight, int32_t iStride ) +{ +#define SRC_FRAME_WIDTH (160) +#define SRC_FRAME_HEIGHT (96) + + if ( SRC_FRAME_WIDTH-iWidth <= 0 || SRC_FRAME_HEIGHT-iHeight <= 0 ) { + return false; + } + + const int32_t kiFrameSize = SRC_FRAME_WIDTH*SRC_FRAME_HEIGHT; + BufferedData sBuf; + sBuf.SetLength(kiFrameSize); + if (sBuf.Length() != kiFrameSize) { + return false; + } + + FileInputStream fileStream; + if (!fileStream.Open("res/CiscoVT2people_160x96_6fps.yuv")) { + return false; + } + if (fileStream.read(sBuf.data(), kiFrameSize) == kiFrameSize) { + srand((uint32_t)time(NULL)); + int32_t iStartPosX = rand()%(SRC_FRAME_WIDTH-iWidth); + int32_t iStartPosY = rand()%(SRC_FRAME_HEIGHT-iHeight); + uint8_t* pSrcPointer = sBuf.data() + iStartPosX + iStartPosY*SRC_FRAME_WIDTH; + uint8_t* pLocalPointer = pPointer; + + for (int j=0;j // use memset/memcmp -#include -#include "../codec/encoder/core/inc/memory_align.h" +#include "gtest/gtest.h" +#include "memory_align.h" using namespace WelsSVCEnc; @@ -46,7 +44,7 @@ TEST(MemoryAlignTest, WelsMallocAndFreeOnceFunctionVerify) const uint32_t kuiExpectedSize = sizeof( void ** ) + sizeof( int32_t ) + kuiExtraAlignSize + uiSize; uint8_t *pUnitTestData = static_cast(cTestMa.WelsMalloc(uiSize, strUnitTestTag)); if ( pUnitTestData != NULL ) { - ASSERT_TRUE( (((int64_t)(static_cast(pUnitTestData))) & kuiExtraAlignSize) == 0 ); + ASSERT_TRUE( (((uintptr_t)(pUnitTestData)) & kuiExtraAlignSize) == 0 ); EXPECT_EQ( kuiExpectedSize, cTestMa.WelsGetMemoryUsage() ); cTestMa.WelsFree( pUnitTestData, strUnitTestTag ); EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() ); diff --git a/test/EncUT_MotionEstimate.cpp b/test/EncUT_MotionEstimate.cpp new file mode 100644 index 00000000..d292ee36 --- /dev/null +++ b/test/EncUT_MotionEstimate.cpp @@ -0,0 +1,125 @@ +#include +#include "gtest/gtest.h" +#include "utils/DataGenerator.h" +#include "md.h" +#include "sample.h" +#include "svc_motion_estimate.h" +#include "wels_func_ptr_def.h" + + +using namespace WelsSVCEnc; + +void CopyTargetBlock( uint8_t* pSrcBlock, const int32_t kiBlockSize, SMVUnitXY sTargetMv, const int32_t kiRefPicStride, + uint8_t* pRefPic) +{ + uint8_t* pTargetPos = pRefPic+sTargetMv.iMvY*kiRefPicStride+sTargetMv.iMvX; + uint8_t* pSourcePos = pSrcBlock; + + for (int i = 0; ipMvdCost = &pMvdCostTable[kuiQp*kuiMvdTableStride + kuiMvdTableMiddle]; + pMe->sMvp.iMvX = pMe->sMvp.iMvY = 0; + pMe->sMvBase.iMvX = pMe->sMvBase.iMvY = 0; + pMe->sMv.iMvX = pMe->sMv.iMvY = 0; +} + +class MotionEstimateTest : public ::testing::Test { +public: + virtual void SetUp() { + m_pRefPic = NULL; + m_pSrcBlock = NULL; + m_pMvdCostTable = NULL; + + m_iWidth = 64;//size of search window + m_iHeight = 64;//size of search window + m_iMaxSearchBlock = 16; + m_uiMvdTableSize = (1 + (648 << 1)); + + m_pRefPic = static_cast + (malloc(m_iWidth*m_iHeight)); + ASSERT_TRUE( NULL != m_pRefPic ); + m_pSrcBlock = static_cast + (malloc(m_iMaxSearchBlock*m_iMaxSearchBlock)); + ASSERT_TRUE( NULL != m_pSrcBlock ); + m_pMvdCostTable=new uint16_t[52*m_uiMvdTableSize]; + ASSERT_TRUE( NULL != m_pMvdCostTable ); + } + virtual void TearDown() { + delete [] m_pMvdCostTable; + free( m_pRefPic ); + free( m_pSrcBlock ); + } +public: + uint8_t *m_pRefPic; + uint8_t *m_pSrcBlock; + uint32_t m_uiMvdTableSize; + uint16_t *m_pMvdCostTable; + + int32_t m_iWidth; + int32_t m_iHeight; + int32_t m_iMaxSearchBlock; +}; + + +TEST_F(MotionEstimateTest, TestDiamondSearch) +{ +#define TEST_POS (5) + const int32_t kiPositionToCheck[TEST_POS][2] = {{0,0}, {0,1}, {1,0}, {0,-1}, {-1,0}}; + 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); + bool bDataGeneratorSucceed = false; + bool bFoundMatch = false; + int32_t i,j,iTryTimes; + for (i=0;i0) { + 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.uiPixel = 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); + + //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) + bFoundMatch = ((sMe.sMv.iMvX==(sTargetMv.iMvX*4))||(sMe.sMv.iMvX==0)) && ((sMe.sMv.iMvY==(sTargetMv.iMvY*4))||(sMe.sMv.iMvY==0)); + } + 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 + } + } +} diff --git a/test/targets.mk b/test/targets.mk index 4e7d6c64..86e72255 100644 --- a/test/targets.mk +++ b/test/targets.mk @@ -3,11 +3,13 @@ CODEC_UNITTEST_CPP_SRCS=\ $(CODEC_UNITTEST_SRCDIR)/BaseDecoderTest.cpp\ $(CODEC_UNITTEST_SRCDIR)/BaseEncoderTest.cpp\ $(CODEC_UNITTEST_SRCDIR)/cpp_interface_test.cpp\ + $(CODEC_UNITTEST_SRCDIR)/DataGenerator.cpp\ $(CODEC_UNITTEST_SRCDIR)/decode_encode_test.cpp\ $(CODEC_UNITTEST_SRCDIR)/decoder_test.cpp\ $(CODEC_UNITTEST_SRCDIR)/encoder_test.cpp\ - $(CODEC_UNITTEST_SRCDIR)/simple_test.cpp\ $(CODEC_UNITTEST_SRCDIR)/EncUT_MemoryAlloc.cpp\ + $(CODEC_UNITTEST_SRCDIR)/EncUT_MotionEstimate.cpp\ + $(CODEC_UNITTEST_SRCDIR)/simple_test.cpp\ CODEC_UNITTEST_OBJS += $(CODEC_UNITTEST_CPP_SRCS:.cpp=.o) diff --git a/test/utils/DataGenerator.h b/test/utils/DataGenerator.h new file mode 100644 index 00000000..a95d84c6 --- /dev/null +++ b/test/utils/DataGenerator.h @@ -0,0 +1,15 @@ +#ifndef DATA_GENERATOR_H__ +#define DATA_GENERATOR_H__ + +#include "typedefs.h" + +bool YUVPixelDataGenerator( uint8_t* pPointer, int32_t iWidth, int32_t iHeight, int32_t iStride ); + +void RandomPixelDataGenerator( uint8_t* pPointer, int32_t iWidth, int32_t iHeight, int32_t iStride ); + +void RandomResidueDataGenerator( uint16_t* pPointer, int32_t iWidth, int32_t iHeight, int32_t iStride ); + +void RandomCoeffDataGenerator( uint16_t* pPointer, int32_t iWidth, int32_t iHeight, int32_t iStride ); + + +#endif//DATA_GENERATOR_H__