#include #include "codec_def.h" #include "mc.h" #include "mem_align.h" #include "cpu_core.h" using namespace WelsDec; #ifdef X86_ASM #define TEST_CASE 0 //TEST_CASE can be 0,WELS_CPU_SSE2 or WELS_CPU_MMXEXT #else #define TEST_CASE 0 #endif #define MC_BUFF_SRC_STRIDE 30 #define MC_BUFF_DST_STRIDE 31 #define MC_BUFF_HEIGHT 30 /**********************MC Unit Test Anchor Code Begin******************************/ bool bQpelNeeded[4][4] = { { false, true, false, true }, { true, true, true, true }, { false, true, false, true }, { true, true, true, true } }; int32_t iHpelRef0Array[4][4] = { { 0, 1, 1, 1 }, { 0, 1, 1, 1 }, { 2, 3, 3, 3 }, { 0, 1, 1, 1 } }; int32_t iHpelRef1Array[4][4] = { { 0, 0, 0, 0 }, { 2, 2, 3, 2 }, { 2, 2, 3, 2 }, { 2, 2, 3, 2 } }; #define FILTER6TAP(pPixBuff, x, iStride) ((pPixBuff)[x-2*iStride] + (pPixBuff)[x+3*iStride] - 5*((pPixBuff)[x-iStride] + (pPixBuff)[x+2*iStride]) + 20*((pPixBuff)[x] + (pPixBuff)[x+iStride])) static inline uint8_t Clip255 (int32_t x) { return ((x & ~255) ? (-x) >> 31 & 255 : x); } void MCCopyAnchor (uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iWidth, int32_t iHeight) { for (int32_t y = 0; y < iHeight; y++) { memcpy (pDst, pSrc, iWidth * sizeof (uint8_t)); pSrc += iSrcStride; pDst += iDstStride; } } void MCHalfPelFilterAnchor (uint8_t* pDstH, uint8_t* pDstV, uint8_t* pDstHV, uint8_t* pSrc, int32_t iStride, int32_t iWidth, int32_t iHeight, int16_t* pBuf) { for (int32_t y = 0; y < iHeight; y++) { for (int32_t x = 0; x < iWidth; x++) pDstH[x] = Clip255 ((FILTER6TAP (pSrc, x, 1) + 16) >> 5); for (int32_t x = -2; x < iWidth + 3; x++) { int32_t v = FILTER6TAP (pSrc, x, iStride); pDstV[x] = Clip255 ((v + 16) >> 5); pBuf[x + 2] = v; } for (int32_t x = 0; x < iWidth; x++) pDstHV[x] = Clip255 ((FILTER6TAP (pBuf + 2, x, 1) + 512) >> 10); pDstH += iStride; pDstV += iStride; pDstHV += iStride; pSrc += iStride; } } void PixelAvgAnchor (uint8_t* pDst, int32_t iDstStride, uint8_t* pSrc1, int32_t iSrc1Stride, uint8_t* pSrc2, int32_t iSrc2Stride, int32_t iWidth, int32_t iHeight) { for (int32_t y = 0; y < iHeight; y++) { for (int32_t x = 0; x < iWidth; x++) pDst[x] = (pSrc1[x] + pSrc2[x] + 1) >> 1; pDst += iDstStride; pSrc1 += iSrc1Stride; pSrc2 += iSrc2Stride; } } void MCLumaAnchor (uint8_t* pDst, int32_t iDstStride, uint8_t* pSrc[4], int32_t iSrcStride, int32_t iMvX, int32_t iMvY, int32_t iWidth, int32_t iHeight) { int32_t iMvXIdx = iMvX & 3; int32_t iMvYIdx = iMvY & 3; int32_t iOffset = (iMvY >> 2) * iSrcStride + (iMvX >> 2); uint8_t* pSrc1 = pSrc[iHpelRef0Array[iMvYIdx][iMvXIdx]] + iOffset + ((iMvYIdx) == 3) * iSrcStride; if (bQpelNeeded[iMvYIdx][iMvXIdx]) { uint8_t* pSrc2 = pSrc[iHpelRef1Array[iMvYIdx][iMvXIdx]] + iOffset + ((iMvXIdx) == 3); PixelAvgAnchor (pDst, iDstStride, pSrc1, iSrcStride, pSrc2, iSrcStride, iWidth, iHeight); } else { MCCopyAnchor (pSrc1, iSrcStride, pDst, iDstStride, iWidth, iHeight); } } void MCChromaAnchor (uint8_t* pDstU, uint8_t* pDstV, int32_t iDstStride, uint8_t* pSrc, int32_t iSrcStride, int32_t iMvX, int32_t iMvY, int32_t iWidth, int32_t iHeight) { uint8_t* pSrcTmp; pSrc += (iMvY >> 3) * iSrcStride + (iMvX >> 3) * 2; pSrcTmp = &pSrc[iSrcStride]; int32_t iMvXIdx = iMvX & 0x07; int32_t iMvYIdx = iMvY & 0x07; int32_t iBiPara0 = (8 - iMvXIdx) * (8 - iMvYIdx); int32_t iBiPara1 = iMvXIdx * (8 - iMvYIdx); int32_t iBiPara2 = (8 - iMvXIdx) * iMvYIdx; int32_t iBiPara3 = iMvXIdx * iMvYIdx; for (int32_t y = 0; y < iHeight; y++) { for (int32_t x = 0; x < iWidth; x++) { pDstU[x] = (iBiPara0 * pSrc[2 * x] + iBiPara1 * pSrc[2 * x + 2] + iBiPara2 * pSrcTmp[2 * x] + iBiPara3 * pSrcTmp[2 * x + 2] + 32) >> 6; pDstV[x] = (iBiPara0 * pSrc[2 * x + 1] + iBiPara1 * pSrc[2 * x + 3] + iBiPara2 * pSrcTmp[2 * x + 1] + iBiPara3 * pSrcTmp[2 * x + 3] + 32) >> 6; } pSrc = pSrcTmp; pSrcTmp += iSrcStride; pDstU += iDstStride; pDstV += iDstStride; } } /**********************MC Unit Test OPENH264 Code Begin******************************/ #define DEF_MCCOPYTEST(iH,iW) \ TEST(McCopy_c,iW##x##iH) \ { \ SMcFunc sMcFunc; \ InitMcFunc(&sMcFunc, TEST_CASE); \ uint8_t uSrcAnchor[MC_BUFF_HEIGHT][MC_BUFF_SRC_STRIDE]; \ uint8_t uSrcTest[MC_BUFF_HEIGHT][MC_BUFF_SRC_STRIDE]; \ uint8_t uDstAnchor[MC_BUFF_HEIGHT][MC_BUFF_DST_STRIDE]; \ uint8_t uDstTest[MC_BUFF_HEIGHT][MC_BUFF_DST_STRIDE]; \ srand((unsigned int)time(0)); \ for(int32_t j=0;j