shithub: openh264

Download patch

ref: bbd3eb29fc7872113e57f53fd8c943c3df93278a
parent: 667bfe26573a4d6e4e85851a3e65f0246479b785
parent: 818203b5e44b60be9d32ff236e97d27d3496c2ce
author: huili2 <[email protected]>
date: Mon Mar 24 18:34:45 EDT 2014

Merge pull request #573 from licaiguo/reorgut2

reorganize tests

--- a/Makefile
+++ b/Makefile
@@ -78,9 +78,7 @@
 
 CODEC_UNITTEST_INCLUDES += \
     -Igtest/include \
-    -Icodec/processing/interface \
     -Icodec/common/inc \
-    -Icodec/encoder/core/inc
 
 H264DEC_INCLUDES = $(DECODER_INCLUDES) -Icodec/console/dec/inc
 H264DEC_LDFLAGS = -L. $(call LINK_LIB,decoder) $(call LINK_LIB,common)
@@ -92,7 +90,9 @@
 
 CODEC_UNITTEST_LDFLAGS = -L. $(call LINK_LIB,gtest) $(call LINK_LIB,decoder) $(call LINK_LIB,encoder) $(call LINK_LIB,processing) $(call LINK_LIB,common) $(CODEC_UNITTEST_LDFLAGS_SUFFIX)
 CODEC_UNITTEST_DEPS = $(LIBPREFIX)gtest.$(LIBSUFFIX) $(LIBPREFIX)decoder.$(LIBSUFFIX) $(LIBPREFIX)encoder.$(LIBSUFFIX) $(LIBPREFIX)processing.$(LIBSUFFIX) $(LIBPREFIX)common.$(LIBSUFFIX)
-
+DECODER_UNITTEST_INCLUDES = $(CODEC_UNITTEST_INCLUDES) $(DECODER_INCLUDES) -Itest -Itest/decoder
+ENCODER_UNITTEST_INCLUDES = $(CODEC_UNITTEST_INCLUDES) $(ENCODER_INCLUDES) -Itest -Itest/encoder
+API_TEST_INCLUDES = $(CODEC_UNITTEST_INCLUDES) -Itest -Itest/api
 .PHONY: test gtest-bootstrap clean
 
 all:	libraries binaries
@@ -155,7 +155,14 @@
 
 ifeq ($(HAVE_GTEST),Yes)
 include build/gtest-targets.mk
-include test/targets.mk
+include test/api/targets.mk
+include test/decoder/targets.mk
+include test/encoder/targets.mk
 endif
 
+binaries: codec_unittest$(EXEEXT)
+BINARIES += codec_unittest$(EXEEXT)
+codec_unittest$(EXEEXT): $(DECODER_UNITTEST_OBJS) $(ENCODER_UNITTEST_OBJS) $(API_TEST_OBJS) $(CODEC_UNITTEST_DEPS)
+	$(QUIET)rm -f $@
+	$(QUIET_CXX)$(CXX) -o $@ $+ $(CODEC_UNITTEST_LDFLAGS) $(LDFLAGS)
 -include $(OBJS:.$(OBJ)=.d)
--- a/build/mktargets.py
+++ b/build/mktargets.py
@@ -7,6 +7,7 @@
 parser.add_argument("--directory", dest="directory", required=True)
 parser.add_argument("--library", dest="library", help="Make a library")
 parser.add_argument("--binary", dest="binary", help="Make a binary")
+parser.add_argument("--prefix", dest="prefix", help="Make a set of objs")
 parser.add_argument("--exclude", dest="exclude", help="Exclude file", action="append")
 parser.add_argument("--include", dest="include", help="Include file", action="append")
 parser.add_argument("--out", dest="out", help="Output file")
@@ -81,8 +82,10 @@
     PREFIX=args.library.upper()
 elif args.binary is not None:
     PREFIX=args.binary.upper()
+elif args.prefix is not None:
+    PREFIX=args.prefix.upper()
 else:
-    sys.stderr.write("Must provide either library or binary")
+    sys.stderr.write("Must provide either library, binary or prefix")
     sys.exit(1)
 
 if args.exclude is not None:
--- a/build/mktargets.sh
+++ b/build/mktargets.sh
@@ -6,5 +6,7 @@
 
 python build/mktargets.py --directory codec/console/dec --binary h264dec
 python build/mktargets.py --directory codec/console/enc --binary h264enc
-python build/mktargets.py --directory test --binary codec_unittest
+python build/mktargets.py --directory test/encoder --prefix encoder_unittest
+python build/mktargets.py --directory test/decoder --prefix decoder_unittest
+python build/mktargets.py --directory test/api --prefix api_test
 python build/mktargets.py --directory gtest --library gtest --out build/gtest-targets.mk --cpp-suffix .cc --include gtest-all.cc
--- a/test/BaseDecoderTest.cpp
+++ /dev/null
@@ -1,171 +1,0 @@
-#include <fstream>
-#include <gtest/gtest.h>
-#include "codec_def.h"
-#include "codec_app_def.h"
-#include "utils/BufferedData.h"
-#include "BaseDecoderTest.h"
-
-static void ReadFrame(std::ifstream* file, BufferedData* buf) {
-  // start code of a frame is {0, 0, 0, 1}
-  int zeroCount = 0;
-  char b;
-
-  buf->Clear();
-  for (;;) {
-    file->read(&b, 1);
-    if (file->gcount() != 1) { // end of file
-      return;
-    }
-    if (!buf->PushBack(b)) {
-      FAIL() << "unable to allocate memory";
-    }
-
-    if (buf->Length() <= 4) {
-      continue;
-    }
-
-    if (zeroCount < 3) {
-      zeroCount = b != 0 ? 0 : zeroCount + 1;
-    } else {
-      if (b == 1) {
-        if (file->seekg(-4, file->cur).good()) {
-          buf->SetLength(buf->Length() - 4);
-          return;
-        } else {
-          FAIL() << "unable to seek file";
-        }
-      } else if (b == 0) {
-        zeroCount = 3;
-      } else {
-        zeroCount = 0;
-      }
-    }
-  }
-}
-
-BaseDecoderTest::BaseDecoderTest()
-  : decoder_(NULL), decodeStatus_(OpenFile) {}
-
-void BaseDecoderTest::SetUp() {
-  long rv = CreateDecoder(&decoder_);
-  ASSERT_EQ(0, rv);
-  ASSERT_TRUE(decoder_ != NULL);
-
-  SDecodingParam decParam;
-  memset(&decParam, 0, sizeof(SDecodingParam));
-  decParam.iOutputColorFormat  = videoFormatI420;
-  decParam.uiTargetDqLayer = UCHAR_MAX;
-  decParam.uiEcActiveFlag  = 1;
-  decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
-
-  rv = decoder_->Initialize(&decParam);
-  ASSERT_EQ(0, rv);
-}
-
-void BaseDecoderTest::TearDown() {
-  if (decoder_ != NULL) {
-    decoder_->Uninitialize();
-    DestroyDecoder(decoder_);
-  }
-}
-
-
-void BaseDecoderTest::DecodeFrame(const uint8_t* src, int sliceSize, Callback* cbk) {
-  void* data[3];
-  SBufferInfo bufInfo;
-  memset(data, 0, sizeof(data));
-  memset(&bufInfo, 0, sizeof(SBufferInfo));
-
-  DECODING_STATE rv = decoder_->DecodeFrame2(src, sliceSize, data, &bufInfo);
-  ASSERT_TRUE(rv == dsErrorFree);
-
-  if (bufInfo.iBufferStatus == 1 && cbk != NULL) {
-    const Frame frame = {
-        { // y plane
-            static_cast<uint8_t*>(data[0]),
-            bufInfo.UsrData.sSystemBuffer.iWidth,
-            bufInfo.UsrData.sSystemBuffer.iHeight,
-            bufInfo.UsrData.sSystemBuffer.iStride[0]
-        },
-        { // u plane
-            static_cast<uint8_t*>(data[1]),
-            bufInfo.UsrData.sSystemBuffer.iWidth / 2,
-            bufInfo.UsrData.sSystemBuffer.iHeight / 2,
-            bufInfo.UsrData.sSystemBuffer.iStride[1]
-        },
-        { // v plane
-            static_cast<uint8_t*>(data[2]),
-            bufInfo.UsrData.sSystemBuffer.iWidth / 2,
-            bufInfo.UsrData.sSystemBuffer.iHeight / 2,
-            bufInfo.UsrData.sSystemBuffer.iStride[1]
-        },
-    };
-    cbk->onDecodeFrame(frame);
-  }
-}
-void BaseDecoderTest::DecodeFile(const char* fileName, Callback* cbk) {
-  std::ifstream file(fileName, std::ios::in | std::ios::binary);
-  ASSERT_TRUE(file.is_open());
-
-  BufferedData buf;
-  while (true) {
-    ReadFrame(&file, &buf);
-    if (::testing::Test::HasFatalFailure()) {
-      return;
-    }
-    if (buf.Length() == 0) {
-      break;
-    }
-    DecodeFrame(buf.data(), buf.Length(), cbk);
-    if (::testing::Test::HasFatalFailure()) {
-      return;
-    }
-  }
-
-  int32_t iEndOfStreamFlag = 1;
-  decoder_->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
-
-  // Get pending last frame
-  DecodeFrame(NULL, 0, cbk);
-}
-
-bool BaseDecoderTest::Open(const char* fileName) {
-  if (decodeStatus_ == OpenFile) {
-    file_.open(fileName, std::ios_base::out | std::ios_base::binary);
-    if (file_.is_open()) {
-      decodeStatus_ = Decoding;
-      return true;
-    }
-  }
-  return false;
-}
-
-bool BaseDecoderTest::DecodeNextFrame(Callback* cbk) {
-  switch (decodeStatus_) {
-  case Decoding:
-    ReadFrame(&file_, &buf_);
-    if (::testing::Test::HasFatalFailure()) {
-      return false;
-    }
-    if (buf_.Length() == 0) {
-      decodeStatus_ = EndOfStream;
-      return true;
-    }
-    DecodeFrame(buf_.data(), buf_.Length(), cbk);
-    if (::testing::Test::HasFatalFailure()) {
-      return false;
-    }
-    return true;
-  case EndOfStream: {
-    int32_t iEndOfStreamFlag = 1;
-    decoder_->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
-    DecodeFrame(NULL, 0, cbk);
-    decodeStatus_ = End;
-    break;
-  }
-  case OpenFile:
-  case End:
-    break;
-  }
-  return false;
-}
--- a/test/BaseEncoderTest.cpp
+++ /dev/null
@@ -1,101 +1,0 @@
-#include <fstream>
-#include <gtest/gtest.h>
-#include "codec_def.h"
-#include "utils/BufferedData.h"
-#include "utils/FileInputStream.h"
-#include "BaseEncoderTest.h"
-
-static int InitWithParam(ISVCEncoder* encoder, int width,
-    int height, float frameRate, SliceModeEnum sliceMode, bool denoise, int deblock, int layers) {
-  if (SM_SINGLE_SLICE == sliceMode && !denoise && deblock == 1 && layers == 1) {
-    SEncParamBase param;
-    memset (&param, 0, sizeof(SEncParamBase));
-
-    param.fMaxFrameRate = frameRate;
-    param.iPicWidth = width;
-    param.iPicHeight = height;
-    param.iTargetBitrate = 5000000;
-    param.iInputCsp = videoFormatI420;
-
-    return encoder->Initialize(&param);
-  } else {
-    SEncParamExt param;
-    encoder->GetDefaultParams(&param);
-
-    param.fMaxFrameRate = frameRate;
-    param.iPicWidth = width;
-    param.iPicHeight = height;
-    param.iTargetBitrate = 5000000;
-    param.iInputCsp = videoFormatI420;
-    param.bEnableDenoise = denoise;
-    param.iLoopFilterDisableIdc = deblock;
-    param.iSpatialLayerNum = layers;
-
-    for (int i = 0; i < param.iSpatialLayerNum; i++) {
-      param.sSpatialLayers[i].iVideoWidth = width >> (param.iSpatialLayerNum - 1 - i);
-      param.sSpatialLayers[i].iVideoHeight = height >> (param.iSpatialLayerNum - 1 - i);
-      param.sSpatialLayers[i].fFrameRate = frameRate;
-      param.sSpatialLayers[i].iSpatialBitrate = param.iTargetBitrate;
-
-      param.sSpatialLayers[i].sSliceCfg.uiSliceMode = sliceMode;
-    }
-
-    return encoder->InitializeExt(&param);
-  }
-}
-
-BaseEncoderTest::BaseEncoderTest() : encoder_(NULL) {}
-
-void BaseEncoderTest::SetUp() {
-  int rv = CreateSVCEncoder(&encoder_);
-  ASSERT_EQ(0, rv);
-  ASSERT_TRUE(encoder_ != NULL);
-}
-
-void BaseEncoderTest::TearDown() {
-  if (encoder_) {
-    encoder_->Uninitialize();
-    DestroySVCEncoder(encoder_);
-  }
-}
-
-void BaseEncoderTest::EncodeStream(InputStream* in, int width, int height,
-    float frameRate, SliceModeEnum slices, bool denoise, int deblock, int layers, Callback* cbk) {
-  int rv = InitWithParam(encoder_, width, height, frameRate, slices, denoise, deblock, layers);
-  ASSERT_TRUE(rv == cmResultSuccess);
-
-  // I420: 1(Y) + 1/4(U) + 1/4(V)
-  int frameSize = width * height * 3 / 2;
-
-  BufferedData buf;
-  buf.SetLength(frameSize);
-  ASSERT_TRUE(buf.Length() == frameSize);
-
-  SFrameBSInfo info;
-  memset(&info, 0, sizeof(SFrameBSInfo));
-
-  SSourcePicture pic;
-  memset(&pic,0,sizeof(SSourcePicture));
-  pic.iPicWidth = width;
-  pic.iPicHeight = height;
-  pic.iColorFormat = videoFormatI420;
-  pic.iStride[0] = pic.iPicWidth;
-  pic.iStride[1] = pic.iStride[2] = pic.iPicWidth>>1;
-  pic.pData[0] = buf.data();
-  pic.pData[1] = pic.pData[0] + width *height;
-  pic.pData[2] = pic.pData[1] + (width*height>>2);
-  while (in->read(buf.data(), frameSize) == frameSize) {
-    rv = encoder_->EncodeFrame(&pic, &info);
-    ASSERT_TRUE(rv == cmResultSuccess);
-    if (info.eOutputFrameType != videoFrameTypeSkip && cbk != NULL) {
-      cbk->onEncodeFrame(info);
-    }
-  }
-}
-
-void BaseEncoderTest::EncodeFile(const char* fileName, int width, int height,
-    float frameRate, SliceModeEnum slices, bool denoise, int deblock, int layers, Callback* cbk) {
-  FileInputStream fileStream;
-  ASSERT_TRUE(fileStream.Open(fileName));
-  EncodeStream(&fileStream, width, height, frameRate, slices, denoise, deblock, layers, cbk);
-}
--- a/test/DataGenerator.cpp
+++ /dev/null
@@ -1,66 +1,0 @@
-#include <string.h>//memset/memcpy
-#include <time.h>
-#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<iHeight;j++) {
-      memcpy(pLocalPointer, pSrcPointer, iWidth*sizeof(uint8_t));
-      pLocalPointer += iStride;
-      pSrcPointer += SRC_FRAME_WIDTH;
-    }
-    return true;
-  }
-  return false;
-}
-
-void RandomPixelDataGenerator( uint8_t* pPointer, int32_t iWidth, int32_t iHeight, int32_t iStride )
-{
-  uint8_t* pLocalPointer = pPointer;
-  for (int32_t j=0;j<iHeight;j++) {
-    for (int32_t i=0;i<iWidth;i++) {
-      pLocalPointer[i] = rand()%256;
-    }
-    pLocalPointer += 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 )
-{
-}
-
--- a/test/DecUT_ExpandPicture.cpp
+++ /dev/null
@@ -1,215 +1,0 @@
-#include<gtest/gtest.h>
-#include "../codec/api/svc/codec_def.h"
-#include "../codec/decoder/core/inc/expand_pic.h"
-#include "../codec/decoder/core/inc/mem_align.h"
-using namespace WelsDec;
-#define EXPAND_PIC_TEST_NUM 10
-namespace WelsDec {
-extern PPicture AllocPicture (PWelsDecoderContext pCtx, const int32_t kPicWidth, const int32_t kPicHeight);
-extern void FreePicture (PPicture pPic);
-}
-#define H264_PADDING_LENGTH_LUMA (PADDING_LENGTH)
-#define H264_PADDING_LENGTH_CHROMA (PADDING_LENGTH>>1)
-
-void H264ExpandPictureLumaAnchor_c (uint8_t* pDst, int32_t iStride, int32_t iPicWidth, int32_t iPicHeight) {
-  uint8_t* pTmp = pDst;
-  uint8_t* pDstLastLine = pTmp + (iPicHeight - 1) * iStride;
-  uint8_t pTL = pTmp[0];
-  uint8_t pTR = pTmp[iPicWidth - 1];
-  uint8_t pBL = pDstLastLine[0];
-  uint8_t pBR = pDstLastLine[iPicWidth - 1];
-  int32_t i = 0;
-
-  do {
-    const int32_t kStrides = (1 + i) * iStride;
-    uint8_t* pTop = pTmp - kStrides;
-    uint8_t* pBottom = pDstLastLine + kStrides;
-
-    // pad pTop and pBottom
-    memcpy (pTop, pTmp, iPicWidth);
-    memcpy (pBottom, pDstLastLine, iPicWidth);
-
-    // pad corners
-    memset (pTop - H264_PADDING_LENGTH_LUMA, pTL, H264_PADDING_LENGTH_LUMA); //pTop left
-    memset (pTop + iPicWidth, pTR, H264_PADDING_LENGTH_LUMA); //pTop right
-    memset (pBottom - H264_PADDING_LENGTH_LUMA, pBL, H264_PADDING_LENGTH_LUMA); //pBottom left
-    memset (pBottom + iPicWidth, pBR, H264_PADDING_LENGTH_LUMA); //pBottom right
-    ++ i;
-  } while (i < H264_PADDING_LENGTH_LUMA);
-
-  // pad left and right
-  i = 0;
-  do {
-    memset (pTmp - H264_PADDING_LENGTH_LUMA, pTmp[0], H264_PADDING_LENGTH_LUMA);
-    memset (pTmp + iPicWidth, pTmp[iPicWidth - 1], H264_PADDING_LENGTH_LUMA);
-    pTmp += iStride;
-    ++ i;
-  } while (i < iPicHeight);
-}
-
-void H264ExpandPictureChromaAnchor_c (uint8_t* pDst, int32_t iStride, int32_t iPicWidth, int32_t iPicHeight) {
-  uint8_t* pTmp = pDst;
-  uint8_t* pDstLastLine = pTmp + (iPicHeight - 1) * iStride;
-  uint8_t pTL = pTmp[0];
-  uint8_t pTR = pTmp[iPicWidth - 1];
-  uint8_t pBL = pDstLastLine[0];
-  uint8_t pBR = pDstLastLine[iPicWidth - 1];
-  int32_t i = 0;
-
-  do {
-    const int32_t kStrides = (1 + i) * iStride;
-    uint8_t* pTop = pTmp - kStrides;
-    uint8_t* pBottom = pDstLastLine + kStrides;
-
-    // pad pTop and pBottom
-    memcpy (pTop, pTmp, iPicWidth);
-    memcpy (pBottom, pDstLastLine, iPicWidth);
-
-    // pad corners
-    memset (pTop - H264_PADDING_LENGTH_CHROMA, pTL, H264_PADDING_LENGTH_CHROMA); //pTop left
-    memset (pTop + iPicWidth, pTR, H264_PADDING_LENGTH_CHROMA); //pTop right
-    memset (pBottom - H264_PADDING_LENGTH_CHROMA, pBL, H264_PADDING_LENGTH_CHROMA); //pBottom left
-    memset (pBottom + iPicWidth, pBR, H264_PADDING_LENGTH_CHROMA); //pBottom right
-
-    ++ i;
-  } while (i < H264_PADDING_LENGTH_CHROMA);
-
-  // pad left and right
-  i = 0;
-  do {
-    memset (pTmp - H264_PADDING_LENGTH_CHROMA, pTmp[0], H264_PADDING_LENGTH_CHROMA);
-    memset (pTmp + iPicWidth, pTmp[iPicWidth - 1], H264_PADDING_LENGTH_CHROMA);
-
-    pTmp += iStride;
-    ++ i;
-  } while (i < iPicHeight);
-}
-
-bool CompareBuff (uint8_t* pSrc0, uint8_t* pSrc1, int32_t iStride, int32_t iWidth, int32_t iHeight) {
-  for (int32_t j = 0; j < iHeight; j++) {
-    for (int32_t i = 0; i < iWidth; i++) {
-      if (pSrc0[i + j * iStride] !=  pSrc1[i + j * iStride]) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-TEST (ExpandPicture, ExpandPictureLuma) {
-  SExpandPicFunc	    sExpandPicFunc;
-  InitExpandPictureFunc (&sExpandPicFunc, 0);
-  srand ((unsigned int)time (0));
-  for (int32_t iTestIdx = 0; iTestIdx < EXPAND_PIC_TEST_NUM; iTestIdx++) {
-    int32_t iPicWidth = 16 + (rand() % 200) * 16;
-    int32_t iPicHeight = 16 + (rand() % 100) * 16;
-
-    int32_t iStride = iPicWidth + H264_PADDING_LENGTH_LUMA * 2;
-    int32_t iBuffHeight = iPicHeight + H264_PADDING_LENGTH_LUMA * 2;
-    int32_t iBuffSize =  iBuffHeight * iStride * sizeof (uint8_t);
-    uint8_t* pAnchorDstBuff = static_cast<uint8_t*> (WelsMalloc (iBuffSize, "pAnchorDstBuff"));
-    uint8_t* pAnchorDst = pAnchorDstBuff + H264_PADDING_LENGTH_LUMA * iStride + H264_PADDING_LENGTH_LUMA;
-
-    uint8_t* pTestDstBuff = static_cast<uint8_t*> (WelsMalloc (iBuffSize, "pTestDstBuff"));
-    uint8_t* pTestDst = pTestDstBuff + H264_PADDING_LENGTH_LUMA * iStride + H264_PADDING_LENGTH_LUMA;
-
-    // Generate Src
-    for (int32_t j = 0; j < iPicHeight; j++) {
-      for (int32_t i = 0; i < iPicWidth; i++) {
-        pAnchorDst[i + j * iStride] = pTestDst[i + j * iStride] = rand() % 256;
-      }
-    }
-    H264ExpandPictureLumaAnchor_c (pAnchorDst, iStride, iPicWidth, iPicHeight);
-    sExpandPicFunc.pExpandLumaPicture (pTestDst, iStride, iPicWidth, iPicHeight);
-    EXPECT_EQ (CompareBuff (pAnchorDstBuff, pTestDstBuff, iStride, iPicWidth + H264_PADDING_LENGTH_LUMA * 2,
-                            iPicHeight + H264_PADDING_LENGTH_LUMA * 2), true);
-
-    WELS_SAFE_FREE (pAnchorDstBuff, "pAnchorDstBuff");
-    WELS_SAFE_FREE (pTestDstBuff, "pTestDstBuff");
-  }
-
-}
-
-TEST (ExpandPicture, ExpandPictureChroma) {
-  SExpandPicFunc	    sExpandPicFunc;
-  InitExpandPictureFunc (&sExpandPicFunc, 0);
-  srand ((unsigned int)time (0));
-
-  for (int32_t iTestIdx = 0; iTestIdx < EXPAND_PIC_TEST_NUM; iTestIdx++) {
-    int32_t iPicWidth = (8 + (rand() % 200) * 8);
-    int32_t iPicHeight = (8 + (rand() % 100) * 8);
-
-    int32_t iStride = (iPicWidth + H264_PADDING_LENGTH_CHROMA * 2 + 8) >> 4 << 4;
-    int32_t iBuffHeight = iPicHeight + H264_PADDING_LENGTH_CHROMA * 2;
-    int32_t iBuffSize =  iBuffHeight * iStride * sizeof (uint8_t);
-    uint8_t* pAnchorDstBuff = static_cast<uint8_t*> (WelsMalloc (iBuffSize, "pAnchorDstBuff"));
-    uint8_t* pAnchorDst = pAnchorDstBuff + H264_PADDING_LENGTH_CHROMA * iStride + H264_PADDING_LENGTH_CHROMA;
-
-    uint8_t* pTestDstBuff = static_cast<uint8_t*> (WelsMalloc (iBuffSize, "pTestDstBuff"));
-    uint8_t* pTestDst = pTestDstBuff + H264_PADDING_LENGTH_CHROMA * iStride + H264_PADDING_LENGTH_CHROMA;
-
-    // Generate Src
-    for (int32_t j = 0; j < iPicHeight; j++) {
-      for (int32_t i = 0; i < iPicWidth; i++) {
-        pAnchorDst[i + j * iStride] =  pTestDst[i + j * iStride] = rand() % 256;
-      }
-    }
-    H264ExpandPictureChromaAnchor_c (pAnchorDst, iStride, iPicWidth, iPicHeight);
-    sExpandPicFunc.pExpandChromaPicture[0] (pTestDst, iStride, iPicWidth, iPicHeight);
-    EXPECT_EQ (CompareBuff (pAnchorDstBuff, pTestDstBuff, iStride, iPicWidth + H264_PADDING_LENGTH_CHROMA * 2,
-                            iPicHeight + H264_PADDING_LENGTH_CHROMA * 2), true);
-
-    WELS_SAFE_FREE (pAnchorDstBuff, "pAnchorDstBuff");
-    WELS_SAFE_FREE (pTestDstBuff, "pTestDstBuff");
-  }
-
-}
-
-TEST (ExpandPicture, ExpandPicForMotion) {
-  SExpandPicFunc	    sExpandPicFunc;
-  InitExpandPictureFunc (&sExpandPicFunc, 0);
-  srand ((unsigned int)time (0));
-  SWelsDecoderContext sCtx;
-  PPicture pPicAnchor = NULL;
-  PPicture pPicTest = NULL;
-  for (int32_t iTestIdx = 0; iTestIdx < EXPAND_PIC_TEST_NUM; iTestIdx++) {
-    int32_t iPicWidth = (16 + (rand() % 200) * 16);
-    int32_t iPicHeight = (16 + (rand() % 100) * 16);
-
-    pPicAnchor = AllocPicture (&sCtx, iPicWidth, iPicHeight);
-    pPicTest = AllocPicture (&sCtx, iPicWidth, iPicHeight);
-    sCtx.pDec = pPicTest;
-
-    int32_t iStride = pPicAnchor->iLinesize[0];
-    int32_t iStrideC;
-    iStrideC = pPicAnchor->iLinesize[1];
-    // Generate Src
-    for (int32_t j = 0; j < iPicHeight; j++) {
-      for (int32_t i = 0; i < iPicWidth; i++) {
-        pPicAnchor->pData[0][i + j * iStride] =  pPicTest->pData[0][i + j * iStride] = rand() % 256;
-      }
-    }
-    for (int32_t j = 0; j < iPicHeight / 2; j++) {
-      for (int32_t i = 0; i < iPicWidth / 2; i++) {
-        pPicAnchor->pData[1][i + j * iStrideC] =  pPicTest->pData[1][i + j * iStrideC] = rand() % 256;
-        pPicAnchor->pData[2][i + j * iStrideC] =  pPicTest->pData[2][i + j * iStrideC] = rand() % 256;
-      }
-    }
-
-    H264ExpandPictureLumaAnchor_c (pPicAnchor->pData[0], iStride, iPicWidth, iPicHeight);
-    H264ExpandPictureChromaAnchor_c (pPicAnchor->pData[1], iStrideC, iPicWidth / 2, iPicHeight / 2);
-    H264ExpandPictureChromaAnchor_c (pPicAnchor->pData[2], iStrideC, iPicWidth / 2, iPicHeight / 2);
-    ExpandReferencingPicture (sCtx.pDec, sExpandPicFunc.pExpandLumaPicture, sExpandPicFunc.pExpandChromaPicture);
-
-    EXPECT_EQ (CompareBuff (pPicAnchor->pBuffer[0], pPicTest->pBuffer[0], iStride, iPicWidth + PADDING_LENGTH * 2,
-                            iPicHeight + PADDING_LENGTH * 2), true);
-    EXPECT_EQ (CompareBuff (pPicAnchor->pBuffer[1], pPicTest->pBuffer[1], iStrideC, iPicWidth / 2 + PADDING_LENGTH,
-                            iPicHeight / 2 + PADDING_LENGTH), true);
-    EXPECT_EQ (CompareBuff (pPicAnchor->pBuffer[2], pPicTest->pBuffer[2], iStrideC, iPicWidth / 2 + PADDING_LENGTH,
-                            iPicHeight / 2 + PADDING_LENGTH), true);
-
-    FreePicture (pPicAnchor);
-    FreePicture (pPicTest);
-  }
-}
-
--- a/test/DecUT_IdctResAddPred.cpp
+++ /dev/null
@@ -1,83 +1,0 @@
-#include <gtest/gtest.h>
-#include <time.h>
-#include "macros.h"
-#include "../codec/decoder/core/inc/decode_mb_aux.h"
-using namespace WelsDec;
-void IdctResAddPred_ref (uint8_t* pPred, const int32_t kiStride, int16_t* pRs) {
-  int16_t iSrc[16];
-
-  uint8_t* pDst			= pPred;
-  const int32_t kiStride2	= kiStride << 1;
-  const int32_t kiStride3	= kiStride + kiStride2;
-  int32_t i;
-
-  for (i = 0; i < 4; i++) {
-    const int32_t kiY  = i << 2;
-    const int32_t kiT0 = pRs[kiY] + pRs[kiY + 2];
-    const int32_t kiT1 = pRs[kiY] - pRs[kiY + 2];
-    const int32_t kiT2 = (pRs[kiY + 1] >> 1) - pRs[kiY + 3];
-    const int32_t kiT3 = pRs[kiY + 1] + (pRs[kiY + 3] >> 1);
-
-    iSrc[kiY] = kiT0 + kiT3;
-    iSrc[kiY + 1] = kiT1 + kiT2;
-    iSrc[kiY + 2] = kiT1 - kiT2;
-    iSrc[kiY + 3] = kiT0 - kiT3;
-  }
-
-  for (i = 0; i < 4; i++) {
-    int32_t kT1	= iSrc[i]	+ iSrc[i + 8];
-    int32_t kT2	= iSrc[i + 4] + (iSrc[i + 12] >> 1);
-    int32_t kT3	= (32 + kT1 + kT2) >> 6;
-    int32_t kT4	= (32 + kT1 - kT2) >> 6;
-
-    pDst[i] = WelsClip1 (kT3 + pPred[i]);
-    pDst[i + kiStride3] = WelsClip1 (kT4 + pPred[i + kiStride3]);
-
-    kT1	= iSrc[i] - iSrc[i + 8];
-    kT2	= (iSrc[i + 4] >> 1) - iSrc[i + 12];
-    pDst[i + kiStride] = WelsClip1 (((32 + kT1 + kT2) >> 6) + pDst[i + kiStride]);
-    pDst[i + kiStride2] = WelsClip1 (((32 + kT1 - kT2) >> 6) + pDst[i + kiStride2]);
-  }
-}
-
-#define GENERATE_IDCTRESADDPRED(pred) \
-TEST(DecoderDecodeMbAux, pred) {\
-  const int32_t kiStride = 32;\
-  const int iBits = 12;\
-  const int iMask = (1 << iBits) - 1;\
-  const int iOffset = 1 << (iBits - 1);\
-  int16_t iRS[16];\
-  uint8_t uiPred[16*kiStride];\
-  int16_t iRefRS[16];\
-  uint8_t uiRefPred[16*kiStride];\
-  int32_t iRunTimes = 1000;\
-  srand((unsigned int)time(NULL));\
-  while(iRunTimes--) {\
-    for(int i = 0; i < 4; i++)\
-      for(int j = 0; j < 4; j++)\
-        iRefRS[i*4+j] = iRS[i*4+j] = (rand() & iMask) - iOffset;\
-    for(int i = 0; i < 4; i++)\
-      for(int j = 0; j < 4; j++)\
-        uiRefPred[i * kiStride + j] = uiPred[i * kiStride + j] = rand() & 255;\
-    pred(uiPred, kiStride, iRS);\
-    IdctResAddPred_ref(uiRefPred, kiStride, iRefRS);\
-    bool ok = true;\
-    for(int i = 0; i < 4; i++)\
-      for(int j = 0; j < 4; j++)\
-        if (uiRefPred[i * kiStride + j] != uiPred[i * kiStride + j]) {\
-          ok = false;\
-          goto next;\
-        }\
-    next:\
-    EXPECT_EQ(ok, true);\
-  }\
-}
-
-GENERATE_IDCTRESADDPRED (IdctResAddPred_c)
-#if defined(X86_ASM)
-GENERATE_IDCTRESADDPRED (IdctResAddPred_mmx)
-#endif
-
-#if defined(HAVE_NEON)
-GENERATE_IDCTRESADDPRED (IdctResAddPred_neon)
-#endif
--- a/test/DecUT_IntraPrediction.cpp
+++ /dev/null
@@ -1,611 +1,0 @@
-#include<gtest/gtest.h>
-#include <time.h>
-#include "../codec/decoder/core/inc/get_intra_predictor.h"
-#include "typedefs.h"
-#include "ls_defines.h"
-using namespace WelsDec;
-#define GENERATE_4x4_UT(pred, ref) \
-  TEST(DecoderIntraPredictionTest, pred) { \
-  const int32_t kiStride = 32; \
-  int32_t iRunTimes = 1000; \
-  uint8_t pPredBuffer[9 * kiStride]; \
-  uint8_t pRefBuffer[9 * kiStride]; \
-  srand((unsigned int)time(NULL)); \
-  while(iRunTimes--) {\
-  for (int i = 0; i < 9; i++) {\
-    pRefBuffer[i] = pPredBuffer[i] = rand() & 255; \
-    pRefBuffer[i * kiStride] = pPredBuffer[i * kiStride] = rand() & 255; \
-  } \
-  pred (&pPredBuffer[kiStride + 1], kiStride); \
-  ref (&pRefBuffer[kiStride + 1], kiStride); \
-  bool ok = true; \
-  for (int i = 0; i < 4; i++) \
-    for (int j = 0; j < 4; j++) \
-      if (pPredBuffer[(i+1) * kiStride + j + 1] != pRefBuffer[(i+1) * kiStride + j + 1]) { \
-        ok = false; \
-        break; \
-      } \
-  EXPECT_EQ(ok, true);\
-  } \
-  }
-
-#define PREDV(size) \
-void LumaI##size##x##size##PredV(uint8_t *pPred, const int32_t kiStride) {\
-  int i; \
-  for (i = 0; i < size; i++) {\
-    memcpy(pPred + i * kiStride, pPred - kiStride, size * sizeof(uint8_t)); \
-  } \
-}
-
-#define PREDH(size) \
-void LumaI##size##x##size##PredH(uint8_t *pPred, const int32_t kiStride) {\
-  for (int i = 0; i < size; i++) { \
-    memset(pPred + i * kiStride, pPred[i * kiStride - 1], size * sizeof(uint8_t));\
-  }\
-}
-
-#define PREDDC(size, log) \
-void LumaI##size##x##size##PredDC(uint8_t *pPred, const int32_t kiStride) {\
-  int iSum = size; \
-  for (int i = 0; i < size; i ++) \
-    iSum += pPred[-1 + i * kiStride] + pPred[i - kiStride]; \
-  uint8_t uiMean = iSum >>(log+1);\
-  for (int i = 0; i < size; i ++) \
-    memset(pPred + i * kiStride, uiMean, size * sizeof(uint8_t)); \
-}
-
-#define PREDDCLeft(size, log) \
-void LumaI##size##x##size##PredDCLeft(uint8_t *pPred, const int32_t kiStride) {\
-  int iSum = size/2; \
-  for (int i = 0; i < size; i ++) \
-    iSum += pPred[-1 + i * kiStride]; \
-  uint8_t uiMean = iSum >>(log);\
-  for (int i = 0; i < size; i ++) \
-    memset(pPred + i * kiStride, uiMean, size * sizeof(uint8_t)); \
-}
-
-#define PREDDCTop(size, log) \
-void LumaI##size##x##size##PredDCTop(uint8_t *pPred, const int32_t kiStride) {\
-  int iSum = size/2; \
-  for (int i = 0; i < size; i ++) \
-    iSum += pPred[i - kiStride]; \
-  uint8_t uiMean = iSum >>(log);\
-  for (int i = 0; i < size; i ++) \
-    memset(pPred + i * kiStride, uiMean, size * sizeof(uint8_t)); \
-}
-
-#define PREDDCNone(size, log) \
-void LumaI##size##x##size##PredDCNone(uint8_t *pPred, const int32_t kiStride) {\
-  uint8_t uiMean = 128;\
-  for (int i = 0; i < size; i ++) \
-    memset(pPred + i * kiStride, uiMean, size * sizeof(uint8_t)); \
-}
-
-
-/*down pLeft*/
-void WelsI4x4LumaPredDDL_ref (uint8_t* pPred, const int32_t kiStride) {
-  const int32_t kiStride2	= kiStride << 1;
-  const int32_t kiStride3	= kiStride + kiStride2;
-  /*get pTop*/
-  uint8_t* ptop			= &pPred[-kiStride];
-  const uint8_t kuiT0		= *ptop;
-  const uint8_t kuiT1		= * (ptop + 1);
-  const uint8_t kuiT2		= * (ptop + 2);
-  const uint8_t kuiT3		= * (ptop + 3);
-  const uint8_t kuiT4		= * (ptop + 4);
-  const uint8_t kuiT5		= * (ptop + 5);
-  const uint8_t kuiT6		= * (ptop + 6);
-  const uint8_t kuiT7		= * (ptop + 7);
-  const uint8_t kuiDDL0	= (2 + kuiT0 + kuiT2 + (kuiT1 << 1)) >> 2;	// kDDL0
-  const uint8_t kuiDDL1	= (2 + kuiT1 + kuiT3 + (kuiT2 << 1)) >> 2;	// kDDL1
-  const uint8_t kuiDDL2	= (2 + kuiT2 + kuiT4 + (kuiT3 << 1)) >> 2;	// kDDL2
-  const uint8_t kuiDDL3	= (2 + kuiT3 + kuiT5 + (kuiT4 << 1)) >> 2;	// kDDL3
-  const uint8_t kuiDDL4	= (2 + kuiT4 + kuiT6 + (kuiT5 << 1)) >> 2;	// kDDL4
-  const uint8_t kuiDDL5	= (2 + kuiT5 + kuiT7 + (kuiT6 << 1)) >> 2;	// kDDL5
-  const uint8_t kuiDDL6	= (2 + kuiT6 + kuiT7 + (kuiT7 << 1)) >> 2;	// kDDL6
-  const uint8_t kuiList[8] = { kuiDDL0, kuiDDL1, kuiDDL2, kuiDDL3, kuiDDL4, kuiDDL5, kuiDDL6, 0 };
-
-  ST32 (pPred          , LD32 (kuiList));
-  ST32 (pPred + kiStride , LD32 (kuiList + 1));
-  ST32 (pPred + kiStride2, LD32 (kuiList + 2));
-  ST32 (pPred + kiStride3, LD32 (kuiList + 3));
-}
-
-/*down pLeft*/
-void WelsI4x4LumaPredDDLTop_ref (uint8_t* pPred, const int32_t kiStride) {
-  const int32_t kiStride2	= kiStride << 1;
-  const int32_t kiStride3	= kiStride + kiStride2;
-  /*get pTop*/
-  uint8_t* ptop			= &pPred[-kiStride];
-  const uint8_t kuiT0		= *ptop;
-  const uint8_t kuiT1		= * (ptop + 1);
-  const uint8_t kuiT2		= * (ptop + 2);
-  const uint8_t kuiT3		= * (ptop + 3);
-  const uint16_t kuiT01	= 1 + kuiT0 + kuiT1;
-  const uint16_t kuiT12	= 1 + kuiT1 + kuiT2;
-  const uint16_t kuiT23	= 1 + kuiT2 + kuiT3;
-  const uint16_t kuiT33	= 1 + (kuiT3 << 1);
-  const uint8_t kuiDLT0	= (kuiT01 + kuiT12) >> 2;	// kDLT0
-  const uint8_t kuiDLT1	= (kuiT12 + kuiT23) >> 2;	// kDLT1
-  const uint8_t kuiDLT2	= (kuiT23 + kuiT33) >> 2;	// kDLT2
-  const uint8_t kuiDLT3	= kuiT33 >> 1;			// kDLT3
-  const uint8_t kuiList[8] = { kuiDLT0, kuiDLT1, kuiDLT2, kuiDLT3, kuiDLT3, kuiDLT3, kuiDLT3 , kuiDLT3 };
-
-  ST32 (pPred,           LD32 (kuiList));
-  ST32 (pPred + kiStride,  LD32 (kuiList + 1));
-  ST32 (pPred + kiStride2, LD32 (kuiList + 2));
-  ST32 (pPred + kiStride3, LD32 (kuiList + 3));
-}
-
-
-/*down right*/
-void WelsI4x4LumaPredDDR_ref (uint8_t* pPred, const int32_t kiStride) {
-  const int32_t kiStride2	= kiStride << 1;
-  const int32_t kiStride3	= kiStride + kiStride2;
-  uint8_t* ptopleft		= &pPred[- (kiStride + 1)];
-  uint8_t* pleft			= &pPred[-1];
-  const uint8_t kuiLT		= *ptopleft;
-  /*get pLeft and pTop*/
-  const uint8_t kuiL0		= *pleft;
-  const uint8_t kuiL1		= * (pleft + kiStride);
-  const uint8_t kuiL2		= * (pleft + kiStride2);
-  const uint8_t kuiL3		= * (pleft + kiStride3);
-  const uint8_t kuiT0		= * (ptopleft + 1);
-  const uint8_t kuiT1		= * (ptopleft + 2);
-  const uint8_t kuiT2		= * (ptopleft + 3);
-  const uint8_t kuiT3		= * (ptopleft + 4);
-  const uint16_t kuiTL0	= 1 + kuiLT + kuiL0;
-  const uint16_t kuiLT0	= 1 + kuiLT + kuiT0;
-  const uint16_t kuiT01	= 1 + kuiT0 + kuiT1;
-  const uint16_t kuiT12	= 1 + kuiT1 + kuiT2;
-  const uint16_t kuiT23	= 1 + kuiT2 + kuiT3;
-  const uint16_t kuiL01	= 1 + kuiL0 + kuiL1;
-  const uint16_t kuiL12	= 1 + kuiL1 + kuiL2;
-  const uint16_t kuiL23	= 1 + kuiL2 + kuiL3;
-  const uint8_t kuiDDR0	= (kuiTL0 + kuiLT0) >> 2;	// kuiDDR0
-  const uint8_t kuiDDR1	= (kuiLT0 + kuiT01) >> 2;	// kuiDDR1
-  const uint8_t kuiDDR2	= (kuiT01 + kuiT12) >> 2;	// kuiDDR2
-  const uint8_t kuiDDR3	= (kuiT12 + kuiT23) >> 2;	// kuiDDR3
-  const uint8_t kuiDDR4	= (kuiTL0 + kuiL01) >> 2;	// kuiDDR4
-  const uint8_t kuiDDR5	= (kuiL01 + kuiL12) >> 2;	// kuiDDR5
-  const uint8_t kuiDDR6	= (kuiL12 + kuiL23) >> 2;	// kuiDDR6
-  const uint8_t kuiList[8] = { kuiDDR6, kuiDDR5, kuiDDR4, kuiDDR0, kuiDDR1, kuiDDR2, kuiDDR3, 0	};
-
-  ST32 (pPred          , LD32 (kuiList + 3));
-  ST32 (pPred + kiStride , LD32 (kuiList + 2));
-  ST32 (pPred + kiStride2, LD32 (kuiList + 1));
-  ST32 (pPred + kiStride3, LD32 (kuiList));
-}
-
-
-/*vertical pLeft*/
-void WelsI4x4LumaPredVL_ref (uint8_t* pPred, const int32_t kiStride) {
-  const int32_t kiStride2	= kiStride << 1;
-  const int32_t kiStride3	= kiStride + kiStride2;
-  uint8_t* ptopleft		= &pPred[- (kiStride + 1)];
-  /*get pTop*/
-  const uint8_t kuiT0		    = * (ptopleft + 1);
-  const uint8_t kuiT1		    = * (ptopleft + 2);
-  const uint8_t kuiT2		    = * (ptopleft + 3);
-  const uint8_t kuiT3		    = * (ptopleft + 4);
-  const uint8_t kuiT4		    = * (ptopleft + 5);
-  const uint8_t kuiT5		    = * (ptopleft + 6);
-  const uint8_t kuiT6		    = * (ptopleft + 7);
-  const uint16_t kuiT01		= 1 + kuiT0 + kuiT1;
-  const uint16_t kuiT12		= 1 + kuiT1 + kuiT2;
-  const uint16_t kuiT23		= 1 + kuiT2 + kuiT3;
-  const uint16_t kuiT34		= 1 + kuiT3 + kuiT4;
-  const uint16_t kuiT45		= 1 + kuiT4 + kuiT5;
-  const uint16_t kuiT56		= 1 + kuiT5 + kuiT6;
-  const uint8_t kuiVL0		= kuiT01 >> 1;			// kuiVL0
-  const uint8_t kuiVL1		= kuiT12 >> 1;			// kuiVL1
-  const uint8_t kuiVL2		= kuiT23 >> 1;			// kuiVL2
-  const uint8_t kuiVL3		= kuiT34 >> 1;			// kuiVL3
-  const uint8_t kuiVL4		= kuiT45 >> 1;			// kuiVL4
-  const uint8_t kuiVL5		= (kuiT01 + kuiT12) >> 2;	// kuiVL5
-  const uint8_t kuiVL6		= (kuiT12 + kuiT23) >> 2;	// kuiVL6
-  const uint8_t kuiVL7		= (kuiT23 + kuiT34) >> 2;	// kuiVL7
-  const uint8_t kuiVL8		= (kuiT34 + kuiT45) >> 2;	// kuiVL8
-  const uint8_t kuiVL9		= (kuiT45 + kuiT56) >> 2;	// kuiVL9
-  const uint8_t kuiList[10]	= { kuiVL0, kuiVL1, kuiVL2, kuiVL3, kuiVL4, kuiVL5, kuiVL6, kuiVL7, kuiVL8, kuiVL9 };
-
-  ST32 (pPred,           LD32 (kuiList));
-  ST32 (pPred + kiStride,  LD32 (kuiList + 5));
-  ST32 (pPred + kiStride2, LD32 (kuiList + 1));
-  ST32 (pPred + kiStride3, LD32 (kuiList + 6));
-}
-
-/*vertical pLeft*/
-void WelsI4x4LumaPredVLTop_ref (uint8_t* pPred, const int32_t kiStride) {
-  const int32_t kiStride2	    = kiStride << 1;
-  const int32_t kiStride3	    = kiStride + kiStride2;
-  uint8_t* ptopleft		    = &pPred[- (kiStride + 1)];
-  /*get pTop*/
-  const uint8_t kuiT0		    = * (ptopleft + 1);
-  const uint8_t kuiT1		    = * (ptopleft + 2);
-  const uint8_t kuiT2		    = * (ptopleft + 3);
-  const uint8_t kuiT3		    = * (ptopleft + 4);
-  const uint16_t kuiT01		= 1 + kuiT0 + kuiT1;
-  const uint16_t kuiT12		= 1 + kuiT1 + kuiT2;
-  const uint16_t kuiT23		= 1 + kuiT2 + kuiT3;
-  const uint16_t kuiT33		= 1 + (kuiT3 << 1);
-  const uint8_t kuiVL0		= kuiT01 >> 1;
-  const uint8_t kuiVL1		= kuiT12 >> 1;
-  const uint8_t kuiVL2		= kuiT23 >> 1;
-  const uint8_t kuiVL3		= kuiT33 >> 1;
-  const uint8_t kuiVL4		= (kuiT01 + kuiT12) >> 2;
-  const uint8_t kuiVL5		= (kuiT12 + kuiT23) >> 2;
-  const uint8_t kuiVL6		= (kuiT23 + kuiT33) >> 2;
-  const uint8_t kuiVL7		= kuiVL3;
-  const uint8_t kuiList[10]	= { kuiVL0, kuiVL1, kuiVL2, kuiVL3, kuiVL3, kuiVL4, kuiVL5, kuiVL6, kuiVL7, kuiVL7 };
-
-  ST32 (pPred          , LD32 (kuiList));
-  ST32 (pPred + kiStride , LD32 (kuiList + 5));
-  ST32 (pPred + kiStride2, LD32 (kuiList + 1));
-  ST32 (pPred + kiStride3, LD32 (kuiList + 6));
-}
-
-
-/*vertical right*/
-void WelsI4x4LumaPredVR_ref (uint8_t* pPred, const int32_t kiStride) {
-  const int32_t kiStride2	    = kiStride << 1;
-  const int32_t kiStride3	    = kiStride + kiStride2;
-  const uint8_t kuiLT		    = pPred[-kiStride - 1];
-  /*get pLeft and pTop*/
-  const uint8_t kuiL0		    = pPred[         -1];
-  const uint8_t kuiL1		    = pPred[kiStride - 1];
-  const uint8_t kuiL2		    = pPred[kiStride2 - 1];
-  const uint8_t kuiT0		    = pPred[ -kiStride];
-  const uint8_t kuiT1		    = pPred[1 - kiStride];
-  const uint8_t kuiT2		    = pPred[2 - kiStride];
-  const uint8_t kuiT3		    = pPred[3 - kiStride];
-  const uint8_t kuiVR0		= (1 + kuiLT + kuiT0) >> 1;	// kuiVR0
-  const uint8_t kuiVR1		= (1 + kuiT0 + kuiT1) >> 1;	// kuiVR1
-  const uint8_t kuiVR2		= (1 + kuiT1 + kuiT2) >> 1;	// kuiVR2
-  const uint8_t kuiVR3		= (1 + kuiT2 + kuiT3) >> 1;	// kuiVR3
-  const uint8_t kuiVR4		= (2 + kuiL0 + (kuiLT << 1) + kuiT0) >> 2;	// kuiVR4
-  const uint8_t kuiVR5		= (2 + kuiLT + (kuiT0 << 1) + kuiT1) >> 2;	// kuiVR5
-  const uint8_t kuiVR6		= (2 + kuiT0 + (kuiT1 << 1) + kuiT2) >> 2;	// kuiVR6
-  const uint8_t kuiVR7		= (2 + kuiT1 + (kuiT2 << 1) + kuiT3) >> 2;	// kuiVR7
-  const uint8_t kuiVR8		= (2 + kuiLT + (kuiL0 << 1) + kuiL1) >> 2;	// kuiVR8
-  const uint8_t kuiVR9		= (2 + kuiL0 + (kuiL1 << 1) + kuiL2) >> 2;	// kuiVR9
-  const uint8_t kuiList[10]	= { kuiVR8, kuiVR0, kuiVR1, kuiVR2, kuiVR3, kuiVR9, kuiVR4, kuiVR5, kuiVR6, kuiVR7 };
-
-  ST32 (pPred          , LD32 (kuiList + 1));
-  ST32 (pPred + kiStride , LD32 (kuiList + 6));
-  ST32 (pPred + kiStride2, LD32 (kuiList));
-  ST32 (pPred + kiStride3, LD32 (kuiList + 5));
-}
-
-/*horizontal up*/
-void WelsI4x4LumaPredHU_ref (uint8_t* pPred, const int32_t kiStride) {
-  const int32_t kiStride2	    = kiStride << 1;
-  const int32_t kiStride3	    = kiStride + kiStride2;
-  /*get pLeft*/
-  const uint8_t kuiL0		    = pPred[         -1];
-  const uint8_t kuiL1		    = pPred[kiStride - 1];
-  const uint8_t kuiL2		    = pPred[kiStride2 - 1];
-  const uint8_t kuiL3		    = pPred[kiStride3 - 1];
-  const uint16_t kuiL01		= 1 + kuiL0 + kuiL1;
-  const uint16_t kuiL12		= 1 + kuiL1 + kuiL2;
-  const uint16_t kuiL23		= 1 + kuiL2 + kuiL3;
-  const uint8_t kuiHU0		= kuiL01 >> 1;
-  const uint8_t kuiHU1		= (kuiL01 + kuiL12) >> 2;
-  const uint8_t kuiHU2		= kuiL12 >> 1;
-  const uint8_t kuiHU3		= (kuiL12 + kuiL23) >> 2;
-  const uint8_t kuiHU4		= kuiL23 >> 1;
-  const uint8_t kuiHU5		= (1 + kuiL23 + (kuiL3 << 1)) >> 2;
-  const uint8_t kuiList[10]	= { kuiHU0, kuiHU1, kuiHU2, kuiHU3, kuiHU4, kuiHU5, kuiL3, kuiL3, kuiL3, kuiL3 };
-
-  ST32 (pPred          , LD32 (kuiList));
-  ST32 (pPred + kiStride , LD32 (kuiList + 2));
-  ST32 (pPred + kiStride2, LD32 (kuiList + 4));
-  ST32 (pPred + kiStride3, LD32 (kuiList + 6));
-}
-
-/*horizontal down*/
-void WelsI4x4LumaPredHD_ref (uint8_t* pPred, const int32_t kiStride) {
-  const int32_t kiStride2 	= kiStride << 1;
-  const int32_t kiStride3	    = kiStride + kiStride2;
-  const uint8_t kuiLT		    = pPred[- (kiStride + 1)];
-  /*get pLeft and pTop*/
-  const uint8_t kuiL0		    = pPred[-1          ];
-  const uint8_t kuiL1		    = pPred[-1 + kiStride ];
-  const uint8_t kuiL2		    = pPred[-1 + kiStride2];
-  const uint8_t kuiL3		    = pPred[-1 + kiStride3];
-  const uint8_t kuiT0		    = pPred[-kiStride   ];
-  const uint8_t kuiT1		    = pPred[-kiStride + 1 ];
-  const uint8_t kuiT2		    = pPred[-kiStride + 2 ];
-  const uint16_t kuiTL0		= 1 + kuiLT + kuiL0;
-  const uint16_t kuiLT0		= 1 + kuiLT + kuiT0;
-  const uint16_t kuiT01		= 1 + kuiT0 + kuiT1;
-  const uint16_t kuiT12		= 1 + kuiT1 + kuiT2;
-  const uint16_t kuiL01		= 1 + kuiL0 + kuiL1;
-  const uint16_t kuiL12		= 1 + kuiL1 + kuiL2;
-  const uint16_t kuiL23		= 1 + kuiL2 + kuiL3;
-  const uint8_t kuiHD0		= kuiTL0 >> 1;
-  const uint8_t kuiHD1		= (kuiTL0 + kuiLT0) >> 2;
-  const uint8_t kuiHD2		= (kuiLT0 + kuiT01) >> 2;
-  const uint8_t kuiHD3		= (kuiT01 + kuiT12) >> 2;
-  const uint8_t kuiHD4		= kuiL01 >> 1;
-  const uint8_t kuiHD5		= (kuiTL0 + kuiL01) >> 2;
-  const uint8_t kuiHD6		= kuiL12 >> 1;
-  const uint8_t kuiHD7		= (kuiL01 + kuiL12) >> 2;
-  const uint8_t kuiHD8		= kuiL23 >> 1;
-  const uint8_t kuiHD9	    = (kuiL12 + kuiL23) >> 2;
-  const uint8_t kuiList[10]	= { kuiHD8, kuiHD9, kuiHD6, kuiHD7, kuiHD4, kuiHD5, kuiHD0, kuiHD1, kuiHD2, kuiHD3 };
-
-  ST32 (pPred          , LD32 (kuiList + 6));
-  ST32 (pPred + kiStride , LD32 (kuiList + 4));
-  ST32 (pPred + kiStride2, LD32 (kuiList + 2));
-  ST32 (pPred + kiStride3, LD32 (kuiList));
-}
-// Unit test for Luma 4x4 cases
-PREDV (4)
-GENERATE_4x4_UT (WelsI4x4LumaPredV_c, LumaI4x4PredV)
-
-PREDH (4)
-GENERATE_4x4_UT (WelsI4x4LumaPredH_c, LumaI4x4PredH)
-
-PREDDC (4, 2)
-GENERATE_4x4_UT (WelsI4x4LumaPredDc_c, LumaI4x4PredDC)
-
-PREDDCLeft (4, 2)
-GENERATE_4x4_UT (WelsI4x4LumaPredDcLeft_c, LumaI4x4PredDCLeft)
-
-PREDDCTop (4, 2)
-GENERATE_4x4_UT (WelsI4x4LumaPredDcTop_c, LumaI4x4PredDCTop)
-
-PREDDCNone (4, 2)
-GENERATE_4x4_UT (WelsI4x4LumaPredDcNA_c, LumaI4x4PredDCNone)
-GENERATE_4x4_UT (WelsI4x4LumaPredDDL_c, WelsI4x4LumaPredDDL_ref)
-GENERATE_4x4_UT (WelsI4x4LumaPredDDLTop_c, WelsI4x4LumaPredDDLTop_ref)
-GENERATE_4x4_UT (WelsI4x4LumaPredDDR_c, WelsI4x4LumaPredDDR_ref)
-GENERATE_4x4_UT (WelsI4x4LumaPredVR_c, WelsI4x4LumaPredVR_ref)
-GENERATE_4x4_UT (WelsI4x4LumaPredVL_c, WelsI4x4LumaPredVL_ref)
-GENERATE_4x4_UT (WelsI4x4LumaPredVLTop_c, WelsI4x4LumaPredVLTop_ref)
-GENERATE_4x4_UT (WelsI4x4LumaPredHU_c, WelsI4x4LumaPredHU_ref)
-GENERATE_4x4_UT (WelsI4x4LumaPredHD_c, WelsI4x4LumaPredHD_ref)
-
-#define GENERATE_8x8_UT(pred, ref) \
-TEST(DecoderIntraPredictionTest, pred) {\
-const int32_t kiStride = 32; \
-int iRunTimes = 1000; \
-uint8_t _pRefBuffer[18 * kiStride + 64]; \
-uint8_t _pPredBuffer[18 * kiStride + 64]; \
-uint8_t *pRefBuffer, *pPredBuffer; \
-pRefBuffer = (uint8_t*)((((intptr_t)(&_pRefBuffer[31])) >> 4) << 4); \
-pPredBuffer = (uint8_t*)((((intptr_t)(&_pPredBuffer[31])) >> 4) << 4); \
-srand((unsigned int)time(NULL)); \
-while(iRunTimes--) {\
-for (int i = 0; i < 17; i ++) {\
-  pRefBuffer[i] = pPredBuffer[i] = rand() & 255; \
-  pRefBuffer[i * kiStride - 1] = pPredBuffer[i * kiStride - 1] = rand() & 255; \
-}\
-pred(&pPredBuffer[kiStride], kiStride); \
-ref(&pRefBuffer[kiStride], kiStride); \
-bool ok = true; \
-for (int i = 0; i < 8; i ++)\
-  for(int j = 0; j < 8; j ++)\
-    if (pPredBuffer[(i+1) * kiStride + j] != pRefBuffer[(i+1) * kiStride + j]) {\
-      ok = false; \
-      break; \
-    } \
-    EXPECT_EQ(ok, true); \
-} \
-}
-
-void WelsIChromaPredPlane_ref (uint8_t* pPred, const int32_t kiStride) {
-  int32_t a = 0, b = 0, c = 0, H = 0, V = 0;
-  int32_t i, j;
-  uint8_t* pTop = &pPred[-kiStride];
-  uint8_t* pLeft = &pPred[-1];
-
-  for (i = 0 ; i < 4 ; i ++) {
-    H += (i + 1) * (pTop[4 + i] - pTop[2 - i]);
-    V += (i + 1) * (pLeft[ (4 + i) * kiStride] - pLeft[ (2 - i) * kiStride]);
-  }
-
-  a = (pLeft[7 * kiStride] + pTop[7]) << 4;
-  b = (17 * H + 16) >> 5;
-  c = (17 * V + 16) >> 5;
-
-  for (i = 0 ; i < 8 ; i ++) {
-    for (j = 0 ; j < 8 ; j ++) {
-      int32_t iTmp = (a + b * (j - 3) + c * (i - 3) + 16) >> 5;
-      pPred[j] = (iTmp < 0) ? 0 : ((iTmp > 255) ? 255 : iTmp);
-    }
-    pPred += kiStride;
-  }
-}
-
-
-void WelsIChromaPredDc_ref (uint8_t* pPred, const int32_t kiStride) {
-  const int32_t kiL1		= kiStride - 1;
-  const int32_t kiL2		= kiL1 + kiStride;
-  const int32_t kiL3		= kiL2 + kiStride;
-  const int32_t kiL4		= kiL3 + kiStride;
-  const int32_t kiL5		= kiL4 + kiStride;
-  const int32_t kiL6		= kiL5 + kiStride;
-  const int32_t kiL7		= kiL6 + kiStride;
-  /*caculate the kMean value*/
-  const uint8_t kuiM1		= (pPred[-kiStride] + pPred[1 - kiStride] + pPred[2 - kiStride] + pPred[3 - kiStride] +
-                           pPred[-1] + pPred[kiL1] + pPred[kiL2] + pPred[kiL3] + 4) >> 3 ;
-  const uint32_t kuiSum2	= pPred[4 - kiStride] + pPred[5 - kiStride] + pPred[6 - kiStride] + pPred[7 - kiStride];
-  const uint32_t kuiSum3	= pPred[kiL4] + pPred[kiL5] + pPred[kiL6] + pPred[kiL7];
-  const uint8_t kuiM2		= (kuiSum2 + 2) >> 2;
-  const uint8_t kuiM3		= (kuiSum3 + 2) >> 2;
-  const uint8_t kuiM4		= (kuiSum2 + kuiSum3 + 4) >> 3;
-  const uint8_t kuiMUP[8]	= {kuiM1, kuiM1, kuiM1, kuiM1, kuiM2, kuiM2, kuiM2, kuiM2};
-  const uint8_t kuiMDown[8]	= {kuiM3, kuiM3, kuiM3, kuiM3, kuiM4, kuiM4, kuiM4, kuiM4};
-  const uint64_t kuiUP64		= LD64 (kuiMUP);
-  const uint64_t kuiDN64		= LD64 (kuiMDown);
-
-  ST64 (pPred       , kuiUP64);
-  ST64 (pPred + kiL1 + 1, kuiUP64);
-  ST64 (pPred + kiL2 + 1, kuiUP64);
-  ST64 (pPred + kiL3 + 1, kuiUP64);
-  ST64 (pPred + kiL4 + 1, kuiDN64);
-  ST64 (pPred + kiL5 + 1, kuiDN64);
-  ST64 (pPred + kiL6 + 1, kuiDN64);
-  ST64 (pPred + kiL7 + 1, kuiDN64);
-}
-
-void WelsIChromaPredDcLeft_ref (uint8_t* pPred, const int32_t kiStride) {
-  const int32_t kiL1	=   -1 + kiStride;
-  const int32_t kiL2	= kiL1 + kiStride;
-  const int32_t kiL3	= kiL2 + kiStride;
-  const int32_t kiL4	= kiL3 + kiStride;
-  const int32_t kiL5	= kiL4 + kiStride;
-  const int32_t kiL6	= kiL5 + kiStride;
-  const int32_t kiL7	= kiL6 + kiStride;
-  /*caculate the kMean value*/
-  const uint8_t kuiMUP   = (pPred[-1] + pPred[kiL1] + pPred[kiL2] + pPred[kiL3] + 2) >> 2 ;
-  const uint8_t kuiMDown = (pPred[kiL4] + pPred[kiL5] + pPred[kiL6] + pPred[kiL7] + 2) >> 2;
-  const uint64_t kuiUP64 = 0x0101010101010101ULL * kuiMUP;
-  const uint64_t kuiDN64 = 0x0101010101010101ULL * kuiMDown;
-
-  ST64 (pPred       , kuiUP64);
-  ST64 (pPred + kiL1 + 1, kuiUP64);
-  ST64 (pPred + kiL2 + 1, kuiUP64);
-  ST64 (pPred + kiL3 + 1, kuiUP64);
-  ST64 (pPred + kiL4 + 1, kuiDN64);
-  ST64 (pPred + kiL5 + 1, kuiDN64);
-  ST64 (pPred + kiL6 + 1, kuiDN64);
-  ST64 (pPred + kiL7 + 1, kuiDN64);
-}
-
-void WelsIChromaPredDcTop_ref (uint8_t* pPred, const int32_t kiStride) {
-  int32_t iTmp			= (kiStride << 3) - kiStride;
-  /*caculate the kMean value*/
-  const uint8_t kuiM1	    = (pPred[-kiStride] + pPred[1 - kiStride] + pPred[2 - kiStride] + pPred[3 - kiStride] + 2) >> 2;
-  const uint8_t kuiM2	    = (pPred[4 - kiStride] + pPred[5 - kiStride] + pPred[6 - kiStride] + pPred[7 - kiStride] + 2) >>
-                            2;
-  const uint8_t kuiM[8]	= {kuiM1, kuiM1, kuiM1, kuiM1, kuiM2, kuiM2, kuiM2, kuiM2};
-
-  uint8_t i = 7;
-
-  do {
-    ST64 (pPred + iTmp, LD64 (kuiM));
-
-    iTmp -= kiStride;
-  } while (i-- > 0);
-}
-PREDV (8)
-PREDH (8)
-PREDDCNone (8, 3)
-GENERATE_8x8_UT (WelsIChromaPredDcNA_c, LumaI8x8PredDCNone)
-GENERATE_8x8_UT (WelsIChromaPredPlane_c, WelsIChromaPredPlane_ref)
-GENERATE_8x8_UT (WelsIChromaPredDc_c, WelsIChromaPredDc_ref)
-GENERATE_8x8_UT (WelsIChromaPredDcTop_c, WelsIChromaPredDcTop_ref)
-GENERATE_8x8_UT (WelsIChromaPredDcLeft_c, WelsIChromaPredDcLeft_ref)
-GENERATE_8x8_UT (WelsIChromaPredH_c, LumaI8x8PredH)
-GENERATE_8x8_UT (WelsIChromaPredV_c, LumaI8x8PredV)
-#define GENERATE_16x16_UT(pred, ref) \
-TEST(DecoderIntraPredictionTest, pred) {\
-const int32_t kiStride = 32; \
-int32_t iRunTimes = 1000; \
-uint8_t _pRefBuffer[18 * kiStride + 64]; \
-uint8_t _pPredBuffer[18 * kiStride + 64]; \
-uint8_t *pRefBuffer, *pPredBuffer; \
-pRefBuffer = (uint8_t*)((((intptr_t)(&_pRefBuffer[31])) >> 4) << 4); \
-pPredBuffer = (uint8_t*)((((intptr_t)(&_pPredBuffer[31])) >> 4) << 4); \
-srand((unsigned int)time(NULL)); \
-while(iRunTimes--) {\
-for (int i = 0; i < 17; i ++) {\
-  pRefBuffer[i] = pPredBuffer[i] = rand() & 255; \
-  pRefBuffer[i * kiStride - 1] = pPredBuffer[i * kiStride - 1] = rand() & 255; \
-}\
-pred(&pPredBuffer[kiStride], kiStride); \
-ref(&pRefBuffer[kiStride], kiStride); \
-bool ok = true; \
-for (int i = 0; i < 16; i ++)\
-  for(int j = 0; j < 16; j ++)\
-    if (pPredBuffer[(i+1) * kiStride + j] != pRefBuffer[(i+1) * kiStride + j]) {\
-      ok = false; \
-      break; \
-    } \
-    EXPECT_EQ(ok, true); \
-} \
-}
-void WelsI16x16LumaPredPlane_ref (uint8_t* pPred, const int32_t kiStride) {
-  int32_t a = 0, b = 0, c = 0, H = 0, V = 0;
-  int32_t i, j;
-  uint8_t* pTop = &pPred[-kiStride];
-  uint8_t* pLeft = &pPred[-1];
-
-  for (i = 0 ; i < 8 ; i ++) {
-    H += (i + 1) * (pTop[8 + i] - pTop[6 - i]);
-    V += (i + 1) * (pLeft[ (8 + i) * kiStride] - pLeft[ (6 - i) * kiStride]);
-  }
-
-  a = (pLeft[15 * kiStride] + pTop[15]) << 4;
-  b = (5 * H + 32) >> 6;
-  c = (5 * V + 32) >> 6;
-
-  for (i = 0 ; i < 16 ; i ++) {
-    for (j = 0 ; j < 16 ; j ++) {
-      int32_t iTmp = (a + b * (j - 7) + c * (i - 7) + 16) >> 5;
-      pPred[j] = (iTmp < 0) ? 0 : ((iTmp > 255) ? 255 : iTmp);
-    }
-    pPred += kiStride;
-  }
-}
-
-PREDV (16)
-PREDH (16)
-PREDDC (16, 4)
-PREDDCTop (16, 4)
-PREDDCLeft (16, 4)
-PREDDCNone (16, 4)
-
-GENERATE_16x16_UT (WelsI16x16LumaPredDcNA_c, LumaI16x16PredDCNone)
-GENERATE_16x16_UT (WelsI16x16LumaPredPlane_c, WelsI16x16LumaPredPlane_ref)
-GENERATE_16x16_UT (WelsI16x16LumaPredDcLeft_c, LumaI16x16PredDCLeft)
-GENERATE_16x16_UT (WelsI16x16LumaPredDcTop_c, LumaI16x16PredDCTop)
-GENERATE_16x16_UT (WelsI16x16LumaPredDc_c, LumaI16x16PredDC)
-GENERATE_16x16_UT (WelsI16x16LumaPredH_c, LumaI16x16PredH)
-GENERATE_16x16_UT (WelsI16x16LumaPredV_c, LumaI16x16PredV)
-#if defined(X86_ASM)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredH_sse2, LumaI4x4PredH)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredDDR_mmx, WelsI4x4LumaPredDDR_ref)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredHD_mmx, WelsI4x4LumaPredHD_ref)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredHU_mmx, WelsI4x4LumaPredHU_ref)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredVR_mmx, WelsI4x4LumaPredVR_ref)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredDDL_mmx, WelsI4x4LumaPredDDL_ref)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredVL_mmx, WelsI4x4LumaPredVL_ref)
-GENERATE_8x8_UT (WelsDecoderIChromaPredDcTop_sse2, WelsIChromaPredDcTop_ref)
-GENERATE_8x8_UT (WelsDecoderIChromaPredDc_sse2, WelsIChromaPredDc_ref)
-GENERATE_8x8_UT (WelsDecoderIChromaPredPlane_sse2, WelsIChromaPredPlane_ref)
-GENERATE_8x8_UT (WelsDecoderIChromaPredH_mmx, LumaI8x8PredH)
-GENERATE_8x8_UT (WelsDecoderIChromaPredV_mmx, LumaI8x8PredV)
-GENERATE_8x8_UT (WelsDecoderIChromaPredDcLeft_mmx, WelsIChromaPredDcLeft_ref)
-GENERATE_8x8_UT (WelsDecoderIChromaPredDcNA_mmx, LumaI8x8PredDCNone)
-GENERATE_16x16_UT (WelsDecoderI16x16LumaPredPlane_sse2, WelsI16x16LumaPredPlane_ref)
-GENERATE_16x16_UT (WelsDecoderI16x16LumaPredH_sse2, LumaI16x16PredH)
-GENERATE_16x16_UT (WelsDecoderI16x16LumaPredV_sse2, LumaI16x16PredV)
-GENERATE_16x16_UT (WelsDecoderI16x16LumaPredDc_sse2, LumaI16x16PredDC)
-GENERATE_16x16_UT (WelsDecoderI16x16LumaPredDcTop_sse2, LumaI16x16PredDCTop)
-GENERATE_16x16_UT (WelsDecoderI16x16LumaPredDcNA_sse2, LumaI16x16PredDCNone)
-#endif
-
-#if defined(HAVE_NEON)
-GENERATE_16x16_UT (WelsDecoderI16x16LumaPredV_neon, LumaI16x16PredV)
-GENERATE_16x16_UT (WelsDecoderI16x16LumaPredH_neon, LumaI16x16PredH)
-GENERATE_16x16_UT (WelsDecoderI16x16LumaPredDc_neon, LumaI16x16PredDC)
-GENERATE_16x16_UT (WelsDecoderI16x16LumaPredPlane_neon, WelsI16x16LumaPredPlane_ref)
-
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredV_neon, LumaI4x4PredV)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredH_neon, LumaI4x4PredH)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredDDL_neon, WelsI4x4LumaPredDDL_ref)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredDDR_neon, WelsI4x4LumaPredDDR_ref)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredVL_neon, WelsI4x4LumaPredVL_ref)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredVR_neon, WelsI4x4LumaPredVR_ref)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredHU_neon, WelsI4x4LumaPredHU_ref)
-GENERATE_4x4_UT (WelsDecoderI4x4LumaPredHD_neon, WelsI4x4LumaPredHD_ref)
-
-GENERATE_8x8_UT (WelsDecoderIChromaPredV_neon, LumaI8x8PredV)
-GENERATE_8x8_UT (WelsDecoderIChromaPredH_neon, LumaI8x8PredH)
-GENERATE_8x8_UT (WelsDecoderIChromaPredDc_neon, WelsIChromaPredDc_ref)
-GENERATE_8x8_UT (WelsDecoderIChromaPredPlane_neon, WelsIChromaPredPlane_ref)
-#endif
--- a/test/DecUT_PredMv.cpp
+++ /dev/null
@@ -1,670 +1,0 @@
-#include<gtest/gtest.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "../codec/decoder/core/inc/wels_common_basis.h"
-#include "../codec/decoder/core/inc/mem_align.h"
-#include "../codec/decoder/core/inc/mv_pred.h"
-#include "ls_defines.h"
-
-using namespace WelsDec;
-
-//Anchor functions
-#define REF_NOT_AVAIL    -2
-#define REF_NOT_IN_LIST  -1  //intra
-
-//cache element equal to 30
-const uint8_t g_kuiAnchorCache30ScanIdx[16] = { //mv or ref_index cache scan index, 4*4 block as basic unit
-  7,  8, 13, 14,
-  9, 10, 15, 16,
-  19, 20, 25, 26,
-  21, 22, 27, 28
-};
-
-typedef struct TagAnchorMvPred {
-  int16_t iMvArray[2][30][2];
-  int8_t iRefIdxArray[2][30];
-  int32_t iPartIdx;
-  int32_t iPartWidth;
-  int32_t iRef;
-  int16_t iMvp[2];
-} SAnchorMvPred;
-
-void AnchorPredMv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
-                   int32_t iPartIdx, int32_t iPartWidth, int8_t iRef, int16_t iMVP[2]) {
-  const uint8_t kuiLeftIdx     = g_kuiAnchorCache30ScanIdx[iPartIdx] - 1;
-  const uint8_t kuiTopIdx      = g_kuiAnchorCache30ScanIdx[iPartIdx] - 6;
-  const uint8_t kuiRightTopIdx = kuiTopIdx + iPartWidth;
-  const uint8_t kuiLeftTopIdx  = kuiTopIdx - 1;
-  const int8_t kiLeftRef       = iRefIndex[0][kuiLeftIdx];
-  const int8_t kiTopRef        = iRefIndex[0][kuiTopIdx];
-  const int8_t kiRightTopRef   = iRefIndex[0][kuiRightTopIdx];
-  const int8_t kiLeftTopRef    = iRefIndex[0][kuiLeftTopIdx];
-  int8_t iDiagonalRef  = kiRightTopRef;
-  int8_t iMatchRef = 0;
-
-  int16_t iAMV[2], iBMV[2], iCMV[2];
-
-  * (int32_t*)iAMV = INTD32 (iMotionVector[0][kuiLeftIdx]);
-  * (int32_t*)iBMV = INTD32 (iMotionVector[0][kuiTopIdx]);
-  * (int32_t*)iCMV = INTD32 (iMotionVector[0][kuiRightTopIdx]);
-
-  if (REF_NOT_AVAIL == iDiagonalRef) {
-    iDiagonalRef = kiLeftTopRef;
-    * (int32_t*)iCMV = INTD32 (iMotionVector[0][kuiLeftTopIdx]);
-  }
-
-  iMatchRef = (iRef == kiLeftRef) + (iRef == kiTopRef) + (iRef == iDiagonalRef);
-
-  if ((REF_NOT_AVAIL == kiTopRef) && (REF_NOT_AVAIL == iDiagonalRef) && (kiLeftRef >= REF_NOT_IN_LIST)) {
-    ST32 (iMVP, LD32 (iAMV));
-    return;
-  }
-
-  if (1 == iMatchRef) {
-    if (iRef == kiLeftRef) {
-      ST32 (iMVP, LD32 (iAMV));
-    } else if (iRef == kiTopRef) {
-      ST32 (iMVP, LD32 (iBMV));
-    } else {
-      ST32 (iMVP, LD32 (iCMV));
-    }
-  } else {
-    iMVP[0] = WelsMedian (iAMV[0], iBMV[0], iCMV[0]);
-    iMVP[1] = WelsMedian (iAMV[1], iBMV[1], iCMV[1]);
-  }
-}
-
-void AnchorPredInter8x16Mv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
-                            int32_t iPartIdx, int8_t iRef, int16_t iMVP[2]) {
-  if (0 == iPartIdx) {
-    const int8_t kiLeftRef = iRefIndex[0][6];
-    if (iRef == kiLeftRef) {
-      ST32 (iMVP, LD32 (&iMotionVector[0][6][0]));
-      return;
-    }
-  } else { // 4 == iPartIdx
-    int8_t iDiagonalRef = iRefIndex[0][5]; //top-right
-    int8_t index = 5;
-    if (REF_NOT_AVAIL == iDiagonalRef) {
-      iDiagonalRef = iRefIndex[0][2]; //top-left for 8*8 block(index 1)
-      index = 2;
-    }
-    if (iRef == iDiagonalRef) {
-      ST32 (iMVP, LD32 (&iMotionVector[0][index][0]));
-      return;
-    }
-  }
-
-  AnchorPredMv (iMotionVector, iRefIndex, iPartIdx, 2, iRef, iMVP);
-}
-
-void AnchorPredInter16x8Mv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
-                            int32_t iPartIdx, int8_t iRef, int16_t iMVP[2]) {
-  if (0 == iPartIdx) {
-    const int8_t kiTopRef = iRefIndex[0][1];
-    if (iRef == kiTopRef) {
-      ST32 (iMVP, LD32 (&iMotionVector[0][1][0]));
-      return;
-    }
-  } else { // 8 == iPartIdx
-    const int8_t kiLeftRef = iRefIndex[0][18];
-    if (iRef == kiLeftRef) {
-      ST32 (iMVP, LD32 (&iMotionVector[0][18][0]));
-      return;
-    }
-  }
-
-  AnchorPredMv (iMotionVector, iRefIndex, iPartIdx, 4, iRef, iMVP);
-}
-
-
-//Ref functions in WelsDec
-//Input structure for test
-typedef struct TagWelsMvPred {
-  int16_t iMvArray[2][30][2];
-  int8_t iRefIdxArray[2][30];
-  int32_t iPartIdx;
-  int32_t iPartWidth;
-  int32_t iRef;
-  int16_t iMvp[2];
-} SWelsMvPred;
-
-//mok input data
-void AssignMvInputData (SAnchorMvPred* pAncMvPred) {
-  int32_t i, j, k;
-  srand ((uint32_t)time (NULL));
-  //fill MV data and refIdx
-  for (i = 0; i < 2; ++i) {
-    for (j = 0; j < 30; ++j) {
-      for (k = 0; k < 2; ++k) {
-        pAncMvPred->iMvArray[i][j][k] = (rand() - RAND_MAX / 2);
-      }
-      pAncMvPred->iRefIdxArray[i][j] = (rand() % 18) - 2; //-2 ~ 15. 8x8 may have different values, but it matters nothing
-    }
-  }
-}
-
-void CopyMvInputData (SAnchorMvPred* pDstMvPred, SWelsMvPred* pSrcMvPred) {
-  int32_t i, j, k;
-  //fill MV data and refIdx
-  for (i = 0; i < 2; ++i) {
-    for (j = 0; j < 30; ++j) {
-      for (k = 0; k < 2; ++k) {
-        pDstMvPred->iMvArray[i][j][k] = pSrcMvPred->iMvArray[i][j][k];
-      }
-      pDstMvPred->iRefIdxArray[i][j] = pSrcMvPred->iRefIdxArray[i][j];
-    }
-  }
-}
-
-#define INIT_MV_DATA \
-  AssignMvInputData (&sAncMvPred); \
-  CopyMvInputData (&sAncMvPred, &sWelsMvPred);
-
-#define TEST_MV_PRED \
-  AnchorPredMv (sAncMvPred.iMvArray,  sAncMvPred.iRefIdxArray, iIndex, iBlockWidth, iRef,  sAncMvPred.iMvp); \
-  PredMv (sWelsMvPred.iMvArray, sWelsMvPred.iRefIdxArray, iIndex, iBlockWidth, iRef, sWelsMvPred.iMvp); \
-  bOK = ((sAncMvPred.iMvp[0] == sWelsMvPred.iMvp[0]) && (sAncMvPred.iMvp[1] == sWelsMvPred.iMvp[1])); \
-  EXPECT_EQ (bOK, true);
-
-
-//TEST cases followed
-
-TEST (PredMvTest, PredMv) {
-  SWelsMvPred  sWelsMvPred;
-  SAnchorMvPred sAncMvPred;
-  int32_t i, iRef, iBlockWidth, iIndex;
-  const int32_t kiRandTime = 100;
-  bool bOK = true;
-
-  //test specific input: 16x16
-  iIndex = 0;
-  iBlockWidth = 4;
-  i = 0;
-  srand ((uint32_t)time (NULL));
-  while (i++ < kiRandTime) {
-    iRef = (rand() % 18) - 2; //-2~15
-    INIT_MV_DATA;
-    TEST_MV_PRED;
-  }
-  //test specific input: 16x8
-  iBlockWidth = 4;
-  i = 0;
-  while (i++ < kiRandTime) {
-    iIndex = (rand() & 1) << 3; //0,8
-    iRef = (rand() % 18) - 2; //-2~15
-    INIT_MV_DATA;
-    TEST_MV_PRED;
-  }
-  //test specific input: 8x16
-  iBlockWidth = 2;
-  i = 0;
-  while (i++ < kiRandTime) {
-    iIndex = (rand() & 1) << 2; //0,4
-    iRef = (rand() % 18) - 2; //-2~15
-    INIT_MV_DATA;
-    TEST_MV_PRED;
-  }
-  //test specific input: 8x8
-  iBlockWidth = 2;
-  i = 0;
-  while (i++ < kiRandTime) {
-    iIndex = (rand() & 3) << 2; //0,4,8,12
-    iRef = (rand() % 18) - 2; //-2~15
-    INIT_MV_DATA;
-    TEST_MV_PRED;
-  }
-  //test specific input: 4x4
-  iBlockWidth = 1;
-  i = 0;
-  while (i++ < kiRandTime) {
-    iIndex = rand() & 0x0f; //0~15
-    iRef = (rand() % 18) - 2; //-2~15
-    INIT_MV_DATA;
-    TEST_MV_PRED;
-  }
-} //TEST PredMv
-
-
-TEST (PredMvTest, PredInter16x8Mv) {
-  SWelsMvPred  sWelsMvPred;
-  SAnchorMvPred sAncMvPred;
-  int32_t i, iRef, iIndex;
-  const int32_t kiRandTime = 100;
-  bool bOK = true;
-
-  i = 0;
-  srand ((uint32_t)time (NULL));
-  while (i++ < kiRandTime) {
-    iIndex = (rand() & 1) << 3; //0, 8
-    iRef = (rand() % 18) - 2; //-2~15
-    INIT_MV_DATA;
-    AnchorPredInter16x8Mv (sAncMvPred.iMvArray,  sAncMvPred.iRefIdxArray, iIndex, iRef,  sAncMvPred.iMvp);
-    PredInter16x8Mv (sWelsMvPred.iMvArray, sWelsMvPred.iRefIdxArray, iIndex, iRef, sWelsMvPred.iMvp);
-    bOK = ((sAncMvPred.iMvp[0] == sWelsMvPred.iMvp[0]) && (sAncMvPred.iMvp[1] == sWelsMvPred.iMvp[1]));
-    EXPECT_EQ (bOK, true);
-  }
-} //TEST PredInter16x8Mv
-
-TEST (PredMvTest, PredInter8x16Mv) {
-  SWelsMvPred  sWelsMvPred;
-  SAnchorMvPred sAncMvPred;
-  int32_t i, iRef, iIndex;
-  const int32_t kiRandTime = 100;
-  bool bOK = true;
-
-  i = 0;
-  srand ((uint32_t)time (NULL));
-  while (i++ < kiRandTime) {
-    iIndex = (rand() & 1) << 2; //0, 4
-    iRef = (rand() % 18) - 2; //-2~15
-    INIT_MV_DATA;
-    AnchorPredInter8x16Mv (sAncMvPred.iMvArray,  sAncMvPred.iRefIdxArray, iIndex, iRef,  sAncMvPred.iMvp);
-    PredInter8x16Mv (sWelsMvPred.iMvArray, sWelsMvPred.iRefIdxArray, iIndex, iRef, sWelsMvPred.iMvp);
-    bOK = ((sAncMvPred.iMvp[0] == sWelsMvPred.iMvp[0]) && (sAncMvPred.iMvp[1] == sWelsMvPred.iMvp[1]));
-    EXPECT_EQ (bOK, true);
-  }
-} //TEST PredInter16x8Mv
-
-void AnchorPredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) {
-  bool bTopAvail, bLeftTopAvail, bRightTopAvail, bLeftAvail;
-
-  int32_t iCurSliceIdc, iTopSliceIdc, iLeftTopSliceIdc, iRightTopSliceIdc, iLeftSliceIdc;
-  int32_t iLeftTopType, iRightTopType, iTopType, iLeftType;
-  int32_t iCurX, iCurY, iCurXy, iLeftXy, iTopXy, iLeftTopXy, iRightTopXy;
-
-  int8_t iLeftRef;
-  int8_t iTopRef;
-  int8_t iRightTopRef;
-  int8_t iLeftTopRef;
-  int8_t iDiagonalRef;
-  int8_t iMatchRef;
-  int16_t iMvA[2], iMvB[2], iMvC[2], iMvD[2];
-
-  iCurXy = pCurLayer->iMbXyIndex;
-  iCurX  = pCurLayer->iMbX;
-  iCurY  = pCurLayer->iMbY;
-  iCurSliceIdc = pCurLayer->pSliceIdc[iCurXy];
-
-  if (iCurX != 0) {
-    iLeftXy = iCurXy - 1;
-    iLeftSliceIdc = pCurLayer->pSliceIdc[iLeftXy];
-    bLeftAvail = (iLeftSliceIdc == iCurSliceIdc);
-  } else {
-    bLeftAvail = 0;
-    bLeftTopAvail = 0;
-  }
-
-  if (iCurY != 0) {
-    iTopXy = iCurXy - pCurLayer->iMbWidth;
-    iTopSliceIdc = pCurLayer->pSliceIdc[iTopXy];
-    bTopAvail = (iTopSliceIdc == iCurSliceIdc);
-    if (iCurX != 0) {
-      iLeftTopXy = iTopXy - 1;
-      iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];
-      bLeftTopAvail = (iLeftTopSliceIdc  == iCurSliceIdc);
-    } else {
-      bLeftTopAvail = 0;
-    }
-    if (iCurX != (pCurLayer->iMbWidth - 1)) {
-      iRightTopXy = iTopXy + 1;
-      iRightTopSliceIdc = pCurLayer->pSliceIdc[iRightTopXy];
-      bRightTopAvail = (iRightTopSliceIdc == iCurSliceIdc);
-    } else {
-      bRightTopAvail = 0;
-    }
-  } else {
-    bTopAvail = 0;
-    bLeftTopAvail = 0;
-    bRightTopAvail = 0;
-  }
-
-  iLeftType = ((iCurX != 0 && bLeftAvail) ? pCurLayer->pMbType[iLeftXy] : 0);
-  iTopType = ((iCurY != 0 && bTopAvail) ? pCurLayer->pMbType[iTopXy] : 0);
-  iLeftTopType = ((iCurX != 0 && iCurY != 0 && bLeftTopAvail)
-                  ? pCurLayer->pMbType[iLeftTopXy] : 0);
-  iRightTopType = ((iCurX != pCurLayer->iMbWidth - 1 && iCurY != 0 && bRightTopAvail)
-                   ? pCurLayer->pMbType[iRightTopXy] : 0);
-
-  /*get neb mv&iRefIdxArray*/
-  /*left*/
-  if (bLeftAvail && IS_INTER (iLeftType)) {
-    ST32 (iMvA, LD32 (pCurLayer->pMv[0][iLeftXy][3]));
-    iLeftRef = pCurLayer->pRefIndex[0][iLeftXy][3];
-  } else {
-    ST32 (iMvA, 0);
-    if (0 == bLeftAvail) { //not available
-      iLeftRef = REF_NOT_AVAIL;
-    } else { //available but is intra mb type
-      iLeftRef = REF_NOT_IN_LIST;
-    }
-  }
-  if (REF_NOT_AVAIL == iLeftRef ||
-      (0 == iLeftRef && 0 == * (int32_t*)iMvA)) {
-    ST32 (iMvp, 0);
-    return;
-  }
-
-  /*top*/
-  if (bTopAvail && IS_INTER (iTopType)) {
-    ST32 (iMvB, LD32 (pCurLayer->pMv[0][iTopXy][12]));
-    iTopRef = pCurLayer->pRefIndex[0][iTopXy][12];
-  } else {
-    ST32 (iMvB, 0);
-    if (0 == bTopAvail) { //not available
-      iTopRef = REF_NOT_AVAIL;
-    } else { //available but is intra mb type
-      iTopRef = REF_NOT_IN_LIST;
-    }
-  }
-  if (REF_NOT_AVAIL == iTopRef ||
-      (0 == iTopRef  && 0 == * (int32_t*)iMvB)) {
-    ST32 (iMvp, 0);
-    return;
-  }
-
-  /*right_top*/
-  if (bRightTopAvail && IS_INTER (iRightTopType)) {
-    ST32 (iMvC, LD32 (pCurLayer->pMv[0][iRightTopXy][12]));
-    iRightTopRef = pCurLayer->pRefIndex[0][iRightTopXy][12];
-  } else {
-    ST32 (iMvC, 0);
-    if (0 == bRightTopAvail) { //not available
-      iRightTopRef = REF_NOT_AVAIL;
-    } else { //available but is intra mb type
-      iRightTopRef = REF_NOT_IN_LIST;
-    }
-  }
-
-  /*left_top*/
-  if (bLeftTopAvail && IS_INTER (iLeftTopType)) {
-    ST32 (iMvD, LD32 (pCurLayer->pMv[0][iLeftTopXy][15]));
-    iLeftTopRef = pCurLayer->pRefIndex[0][iLeftTopXy][15];
-  } else {
-    ST32 (iMvD, 0);
-    if (0 == bLeftTopAvail) { //not available
-      iLeftTopRef = REF_NOT_AVAIL;
-    } else { //available but is intra mb type
-      iLeftTopRef = REF_NOT_IN_LIST;
-    }
-  }
-
-  iDiagonalRef = iRightTopRef;
-  if (REF_NOT_AVAIL == iDiagonalRef) {
-    iDiagonalRef = iLeftTopRef;
-    * (int32_t*)iMvC = * (int32_t*)iMvD;
-  }
-
-  if (REF_NOT_AVAIL == iTopRef && REF_NOT_AVAIL == iDiagonalRef && iLeftRef >= REF_NOT_IN_LIST) {
-    ST32 (iMvp, LD32 (iMvA));
-    return;
-  }
-
-  iMatchRef = (0 == iLeftRef) + (0 == iTopRef) + (0 == iDiagonalRef);
-  if (1 == iMatchRef) {
-    if (0 == iLeftRef) {
-      ST32 (iMvp, LD32 (iMvA));
-    } else if (0 == iTopRef) {
-      ST32 (iMvp, LD32 (iMvB));
-    } else {
-      ST32 (iMvp, LD32 (iMvC));
-    }
-  } else {
-    iMvp[0] = WelsMedian (iMvA[0], iMvB[0], iMvC[0]);
-    iMvp[1] = WelsMedian (iMvA[1], iMvB[1], iMvC[1]);
-  }
-}
-
-
-
-int32_t AllocLayerData (PDqLayer pDqLayer) {
-
-  pDqLayer->pSliceIdc = (int32_t*) WelsMalloc (pDqLayer->iMbWidth * pDqLayer->iMbHeight * sizeof (int32_t),
-                        "pDqLayer->pSliceIdc");
-  if (pDqLayer->pSliceIdc == NULL)
-    return 1;
-
-  pDqLayer->pMbType = (int8_t*) WelsMalloc (pDqLayer->iMbWidth * pDqLayer->iMbHeight * sizeof (int8_t),
-                      "pDqLayer->pMbType");
-  if (pDqLayer->pMbType == NULL)
-    return 1;
-
-  pDqLayer->pMv[0] = (int16_t (*)[MB_BLOCK4x4_NUM][MV_A]) WelsMalloc (pDqLayer->iMbWidth * pDqLayer->iMbHeight * sizeof (
-                       int16_t) * MV_A * MB_BLOCK4x4_NUM, "pDqLayer->pMv");
-  if (pDqLayer->pMv[0] == NULL)
-    return 1;
-
-  pDqLayer->pRefIndex[0] = (int8_t (*)[MB_BLOCK4x4_NUM]) WelsMalloc (pDqLayer->iMbWidth * pDqLayer->iMbHeight * sizeof (
-                             int8_t) * MB_BLOCK4x4_NUM, "pDqLayer->pRefIndex");
-  if (pDqLayer->pRefIndex[0] == NULL)
-    return 1;
-
-  return 0;
-}
-
-int32_t FreeLayerData (PDqLayer pDqLayer) {
-
-  if (pDqLayer->pSliceIdc != NULL) {
-    WelsFree (pDqLayer->pSliceIdc, "pDqLayer->pSliceIdc");
-    pDqLayer->pSliceIdc = NULL;
-  }
-
-  if (pDqLayer->pMbType != NULL) {
-    WelsFree (pDqLayer->pMbType, "pDqLayer->pMbType");
-    pDqLayer->pMbType = NULL;
-  }
-
-  if (pDqLayer->pMv[0] != NULL) {
-    WelsFree (pDqLayer->pMv[0], "pDqlayer->pMv[0]");
-    pDqLayer->pMv[0] = NULL;
-  }
-
-  if (pDqLayer->pRefIndex[0] != NULL) {
-    WelsFree (pDqLayer->pRefIndex[0], "pDqlayer->pRefIndex[0]");
-    pDqLayer->pRefIndex[0] = NULL;
-  }
-
-  return 0;
-}
-
-void InitRandomLayerSliceIdc (PDqLayer pDqLayer) {
-  srand ((uint32_t)time (NULL));
-  int32_t i = 0;
-  int32_t iTotalMbNum = pDqLayer->iMbWidth * pDqLayer->iMbHeight;
-  int32_t iMbFirstSliceEnd = rand() % (iTotalMbNum - 1); //assure 2 slices
-  for (i = 0; i <= iMbFirstSliceEnd; ++i) {
-    pDqLayer->pSliceIdc[i] = 0; //to keep simple value here
-  }
-  for (; i < iTotalMbNum; ++i) {
-    pDqLayer->pSliceIdc[i] = 1; //to keep simple value here
-  }
-}
-
-void InitRandomLayerMbType (PDqLayer pDqLayer) {
-  srand ((uint32_t)time (NULL));
-  for (int32_t i = 0; i < pDqLayer->iMbWidth * pDqLayer->iMbHeight; ++i) {
-    pDqLayer->pMbType[i] = (rand() & 0x0f) + 1; //1 ~ 16
-  }
-}
-
-void InitRandomLayerMvData (PDqLayer pDqLayer) {
-  srand ((uint32_t)time (NULL));
-  for (int32_t i = 0; i < pDqLayer->iMbWidth * pDqLayer->iMbHeight; ++i) {
-    for (int32_t j = 0; j < MB_BLOCK4x4_NUM; ++j) {
-      for (int32_t k = 0; k < MV_A; ++k) {
-        pDqLayer->pMv[0][i][j][k] = (rand() - RAND_MAX / 2);
-      }
-    }
-  }
-}
-
-void InitRandomLayerRefIdxData (PDqLayer pDqLayer) {
-  srand ((uint32_t)time (NULL));
-  for (int32_t i = 0; i < pDqLayer->iMbWidth * pDqLayer->iMbHeight; ++i) {
-    for (int32_t j = 0; j < MB_BLOCK4x4_NUM; ++j) {
-      pDqLayer->pRefIndex[0][i][j] = (rand() % 18 - 2); //-2 ~ 15
-    }
-  }
-}
-
-void InitRandomLayerData (PDqLayer pDqLayer) {
-  InitRandomLayerSliceIdc (pDqLayer);
-  InitRandomLayerMbType (pDqLayer);
-  InitRandomLayerMvData (pDqLayer);
-  InitRandomLayerRefIdxData (pDqLayer);
-}
-
-#define TEST_SKIP_MV_PRED \
-  PredPSkipMvFromNeighbor (&sDqLayer, iWelsMvp); \
-  bOK = ((iWelsMvp[0] == iAncMvp[0]) && (iWelsMvp[1] == iAncMvp[1])); \
-  EXPECT_EQ (bOK, true);
-
-TEST (PredMvTest, PredSkipMvFromNeighbor) {
-  const int32_t kiRandTime = 100;
-  bool bOK = true;
-  SDqLayer sDqLayer;
-  int16_t iAncMvp[2], iWelsMvp[2];
-
-  memset (&sDqLayer, 0, sizeof (SDqLayer));
-  //Assume the input data as 352x288 size
-  //allocate the data
-  sDqLayer.iMbWidth = 11;
-  sDqLayer.iMbHeight = 9;
-  if (AllocLayerData (&sDqLayer)) { //memory allocate failed
-    FreeLayerData (&sDqLayer);
-    return;
-  }
-  InitRandomLayerData (&sDqLayer); //init MV data, as it would not affect the following logic test
-
-#define CURR_MB_IDX (sDqLayer.iMbXyIndex)
-#define LEFT_MB_IDX (sDqLayer.iMbXyIndex - 1)
-#define LEFT_MB_BLK 3
-#define TOP_MB_IDX (sDqLayer.iMbXyIndex - sDqLayer.iMbWidth)
-#define TOP_MB_BLK 12
-#define LEFT_TOP_MB_IDX (sDqLayer.iMbXyIndex - sDqLayer.iMbWidth - 1)
-#define LEFT_TOP_MB_BLK 15
-#define RIGHT_TOP_MB_IDX (sDqLayer.iMbXyIndex - sDqLayer.iMbWidth + 1)
-#define RIGHT_TOP_MB_BLK 12
-
-  //CASE 1: test MB [0,0], expect mvp = (0,0)
-  sDqLayer.iMbX = 0;
-  sDqLayer.iMbY = 0;
-  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
-  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
-  TEST_SKIP_MV_PRED;
-  //CASE 2: test MB [ANY, 0], expect mvp = (0,0)
-  sDqLayer.iMbX = rand() % sDqLayer.iMbWidth;
-  sDqLayer.iMbY = 0;
-  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
-  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
-  TEST_SKIP_MV_PRED;
-  //CASE 3: test MB [0, ANY], expect mvp = (0,0)
-  sDqLayer.iMbX = 0;
-  sDqLayer.iMbY = rand() % sDqLayer.iMbHeight;
-  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
-  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
-  TEST_SKIP_MV_PRED;
-  //CASE 4.1: test MB [RIGHT_SIDE, ANY]
-  sDqLayer.iMbX = sDqLayer.iMbWidth - 1;
-  sDqLayer.iMbY = rand() % (sDqLayer.iMbHeight - 1) + 1; //not equal to 0
-  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
-  //CASE 4.1.1: same slice_idc, assume = 0
-  memset (sDqLayer.pSliceIdc, 0, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int32_t));
-  //CASE 4.1.1.1: ALL P modes
-  memset (sDqLayer.pMbType, MB_TYPE_16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t));
-  //CASE 4.1.1.1.1: ref_idx = 0, left MV = 0, top MV != 0, expect mvp = (0,0)
-  memset (sDqLayer.pRefIndex[0], 0, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (int8_t));
-  InitRandomLayerMvData (&sDqLayer); //reset Mv data
-  sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][0] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][1] = 0; //left_mv = 0
-  sDqLayer.pMv[0][ TOP_MB_IDX][ TOP_MB_BLK][0] = sDqLayer.pMv[0][ TOP_MB_IDX][ TOP_MB_BLK][1] = 1; //top_mv != 0
-  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
-  TEST_SKIP_MV_PRED;
-  //CASE 4.1.1.1.2: ref_idx = 0, left MV != 0, top MV = 0, expect mvp = (0,0)
-  memset (sDqLayer.pRefIndex[0], 0, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (int8_t));
-  InitRandomLayerMvData (&sDqLayer); //reset Mv data
-  sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][0] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][1] = 1; //left_mv != 0
-  sDqLayer.pMv[0][ TOP_MB_IDX][ TOP_MB_BLK][0] = sDqLayer.pMv[0][ TOP_MB_IDX][ TOP_MB_BLK][1] = 0; //top_mv = 0
-  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
-  TEST_SKIP_MV_PRED;
-  //CASE 4.1.1.1.3: ref_idx top = 0, others = 1, expect mvp = top mv
-  InitRandomLayerMvData (&sDqLayer); //reset Mv data
-  sDqLayer.pRefIndex[0][ TOP_MB_IDX][ TOP_MB_BLK] = 0; //top ref_idx = 0
-  sDqLayer.pRefIndex[0][LEFT_MB_IDX][LEFT_MB_BLK] = 1; //left ref_idx = 1
-  sDqLayer.pRefIndex[0][LEFT_TOP_MB_IDX][LEFT_TOP_MB_BLK] = 1; //left_top ref_idx = 1
-  iAncMvp[0] = sDqLayer.pMv[0][TOP_MB_IDX][TOP_MB_BLK][0];
-  iAncMvp[1] = sDqLayer.pMv[0][TOP_MB_IDX][TOP_MB_BLK][1];
-  TEST_SKIP_MV_PRED;
-  //CASE 4.1.1.1.4: ref_idx left = 0, others = 1, expect mvp = left mv
-  sDqLayer.pRefIndex[0][ TOP_MB_IDX][ TOP_MB_BLK] = 1; //top ref_idx = 1
-  sDqLayer.pRefIndex[0][LEFT_MB_IDX][LEFT_MB_BLK] = 0; //left ref_idx = 0
-  sDqLayer.pRefIndex[0][LEFT_TOP_MB_IDX][LEFT_TOP_MB_BLK] = 1; //left_top ref_idx = 1
-  iAncMvp[0] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][0];
-  iAncMvp[1] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][1];
-  TEST_SKIP_MV_PRED;
-  //CASE 4.1.1.2: All I
-  memset (sDqLayer.pMbType, MB_TYPE_INTRA16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t));
-  //CASE 4.1.1.2.1: left P, expect mvp = left mv
-  sDqLayer.pMbType[LEFT_MB_IDX] = MB_TYPE_16x16; //left P
-  iAncMvp[0] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][0];
-  iAncMvp[1] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][1];
-  TEST_SKIP_MV_PRED;
-  //CASE 4.1.1.3: only top P, top ref_idx = 0, expect mvp = top mv
-  memset (sDqLayer.pMbType, MB_TYPE_INTRA16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t)); // All I MB
-  memset (sDqLayer.pRefIndex[0], 1, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (
-            int8_t)); // All ref_idx = 1
-  sDqLayer.pMbType[TOP_MB_IDX] = MB_TYPE_16x16; //top P
-  sDqLayer.pRefIndex[0][TOP_MB_IDX][TOP_MB_BLK] = 0; //top ref_idx = 0
-  iAncMvp[0] = sDqLayer.pMv[0][TOP_MB_IDX][TOP_MB_BLK][0];
-  iAncMvp[1] = sDqLayer.pMv[0][TOP_MB_IDX][TOP_MB_BLK][1];
-  TEST_SKIP_MV_PRED;
-  //CASE 4.1.1.4: only left_top P, left_top ref_idx = 0, expect mvp = 0
-  sDqLayer.iMbX = (rand() % (sDqLayer.iMbWidth - 2)) + 1; //1 ~ (mb_width - 2)
-  sDqLayer.iMbY = (rand() % (sDqLayer.iMbHeight - 2)) + 1; //1 ~ (mb_height - 2)
-  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
-  memset (sDqLayer.pMbType, MB_TYPE_INTRA16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t)); // All I MB
-  memset (sDqLayer.pRefIndex[0], 1, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (
-            int8_t)); // All ref_idx = 1
-  sDqLayer.pMbType[LEFT_TOP_MB_IDX] = MB_TYPE_16x16; //top P
-  sDqLayer.pRefIndex[0][LEFT_TOP_MB_IDX][LEFT_TOP_MB_BLK] = 0; //top ref_idx = 0
-  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
-  TEST_SKIP_MV_PRED;
-  //CASE 4.1.1.5: only right_top P, right_top ref_idx = 0, expect mvp = right_top mv
-  sDqLayer.iMbX = (rand() % (sDqLayer.iMbWidth - 2)) + 1; //1 ~ (mb_width - 2)
-  sDqLayer.iMbY = (rand() % (sDqLayer.iMbHeight - 2)) + 1; //1 ~ (mb_height - 2)
-  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
-  memset (sDqLayer.pMbType, MB_TYPE_INTRA16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t)); // All I MB
-  memset (sDqLayer.pRefIndex[0], 1, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (
-            int8_t)); // All ref_idx = 1
-  sDqLayer.pMbType[RIGHT_TOP_MB_IDX] = MB_TYPE_16x16; //top P
-  sDqLayer.pRefIndex[0][RIGHT_TOP_MB_IDX][RIGHT_TOP_MB_BLK] = 0; //top ref_idx = 0
-  iAncMvp[0] = sDqLayer.pMv[0][RIGHT_TOP_MB_IDX][RIGHT_TOP_MB_BLK][0];
-  iAncMvp[1] = sDqLayer.pMv[0][RIGHT_TOP_MB_IDX][RIGHT_TOP_MB_BLK][1];
-  TEST_SKIP_MV_PRED;
-  //CASE 4.1.2: different neighbor slice idc for all P and ref_idx = 0, expect mvp = 0
-  memset (sDqLayer.pMbType, MB_TYPE_16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t)); // All I MB
-  memset (sDqLayer.pRefIndex[0], 0, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (
-            int8_t)); // All ref_idx = 1
-  sDqLayer.iMbX = (rand() % (sDqLayer.iMbWidth - 2)) + 1; //1 ~ (mb_width - 2)
-  sDqLayer.iMbY = (rand() % (sDqLayer.iMbHeight - 2)) + 1; //1 ~ (mb_height - 2)
-  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
-  sDqLayer.pSliceIdc[CURR_MB_IDX] = 5;
-  sDqLayer.pSliceIdc[LEFT_MB_IDX] = 0;
-  sDqLayer.pSliceIdc[TOP_MB_IDX] = 1;
-  sDqLayer.pSliceIdc[LEFT_TOP_MB_IDX] = 2;
-  sDqLayer.pSliceIdc[RIGHT_TOP_MB_IDX] = 3;
-  iAncMvp[0] = iAncMvp[1] = 0;
-  TEST_SKIP_MV_PRED;
-
-  //add new specific tests here
-
-  //normal tests
-  int32_t i = 0;
-  while (i++ < kiRandTime) {
-    InitRandomLayerData (&sDqLayer); //init MV data, as it would not affect the following logic test
-    AnchorPredPSkipMvFromNeighbor (&sDqLayer, iAncMvp);
-    TEST_SKIP_MV_PRED;
-  }
-
-  FreeLayerData (&sDqLayer);
-}
--- a/test/EncUT_MemoryAlloc.cpp
+++ /dev/null
@@ -1,63 +1,0 @@
-#include <time.h>
-
-#include "gtest/gtest.h"
-#include "memory_align.h"
-
-using namespace WelsSVCEnc;
-
-//Tests of WelsGetCacheLineSize Begin
-TEST(MemoryAlignTest, GetCacheLineSize_LoopWithin16K)
-{
-  const unsigned int kuiTestBoundary16K = 16 * 1024;
-	unsigned int uiTargetAlign = 1;
-	while (uiTargetAlign < kuiTestBoundary16K) {
-		CMemoryAlign cTestMa(uiTargetAlign);
-    ASSERT_EQ(  (uiTargetAlign & 0x0F)?16:uiTargetAlign, cTestMa.WelsGetCacheLineSize() );
-		++ uiTargetAlign;
-	}
-}
-
-TEST(MemoryAlignTest, GetCacheLineSize_Zero)
-{
-  CMemoryAlign cTestMa(0);
-  ASSERT_EQ(  16, cTestMa.WelsGetCacheLineSize() );
-}
-TEST(MemoryAlignTest, GetCacheLineSize_MaxUINT)
-{
-	CMemoryAlign cTestMa(0xFFFFFFFF);
-	ASSERT_EQ( 16, cTestMa.WelsGetCacheLineSize() );
-}
-//Tests of WelsGetCacheLineSize End
-//Tests of WelsMallocAndFree Begin
-TEST(MemoryAlignTest, WelsMallocAndFreeOnceFunctionVerify)
-{
-  const uint32_t kuiTargetAlignSize[4] = {32, 16, 64, 8};
-  srand((uint32_t)time(NULL));
-
-  for (int i=0; i<4; i++) {
-    const uint32_t kuiTestAlignSize	= kuiTargetAlignSize[i];
-    const uint32_t kuiTestDataSize		= abs(rand());
-
-    CMemoryAlign cTestMa(kuiTestAlignSize);
-    const uint32_t uiSize = kuiTestDataSize;
-    const char strUnitTestTag[100] = "pUnitTestData";
-    const uint32_t kuiUsedCacheLineSize	= ((kuiTestAlignSize == 0) || (kuiTestAlignSize & 0x0F)) ? (16) : (kuiTestAlignSize);
-    const uint32_t kuiExtraAlignSize	= kuiUsedCacheLineSize-1;
-    const uint32_t kuiExpectedSize	= sizeof( void ** ) + sizeof( int32_t ) + kuiExtraAlignSize + uiSize;
-    uint8_t *pUnitTestData = static_cast<uint8_t *>(cTestMa.WelsMalloc(uiSize, strUnitTestTag));
-    if ( pUnitTestData != NULL ) {
-      ASSERT_TRUE( (((uintptr_t)(pUnitTestData)) & kuiExtraAlignSize) == 0 );
-      EXPECT_EQ( kuiExpectedSize, cTestMa.WelsGetMemoryUsage() );
-      cTestMa.WelsFree( pUnitTestData, strUnitTestTag );
-      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
-    }
-    else {
-      EXPECT_EQ( NULL, pUnitTestData );
-      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
-      cTestMa.WelsFree( pUnitTestData, strUnitTestTag );
-      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
-    }
-  }
-}
-
-
--- a/test/EncUT_MotionEstimate.cpp
+++ /dev/null
@@ -1,125 +1,0 @@
-#include <stdlib.h>
-#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; i<kiBlockSize; i++) {
-    memcpy( pSourcePos, pTargetPos, kiBlockSize*sizeof(uint8_t) );
-    pTargetPos += kiRefPicStride;
-    pSourcePos += kiBlockSize;
-  }
-}
-
-
-void InitMe( const uint8_t kuiQp, const uint32_t kuiMvdTableMiddle, const uint32_t kuiMvdTableStride,
-            uint16_t* pMvdCostTable, SWelsME* pMe)
-{
-  MvdCostInit( pMvdCostTable, kuiMvdTableStride );
-  pMe->pMvdCost = &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<uint8_t *>
-    (malloc(m_iWidth*m_iHeight));
-    ASSERT_TRUE( NULL != m_pRefPic );
-    m_pSrcBlock = static_cast<uint8_t *>
-    (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, iTryTimes;
-  for (i=0;i<TEST_POS;i++) {
-    sTargetMv.iMvX = kiPositionToCheck[i][0];
-    sTargetMv.iMvY = kiPositionToCheck[i][1];
-    iTryTimes = 100;
-    bDataGeneratorSucceed = false;
-    bFoundMatch = false;
-    while (!bFoundMatch && (iTryTimes--)>0) {
-      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))||(sMe.sMv.iMvX==0)) && ((sMe.sMv.iMvY==(sTargetMv.iMvY))||(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
-    }
-  }
-}
--- /dev/null
+++ b/test/api/BaseDecoderTest.cpp
@@ -1,0 +1,171 @@
+#include <fstream>
+#include <gtest/gtest.h>
+#include "codec_def.h"
+#include "codec_app_def.h"
+#include "utils/BufferedData.h"
+#include "BaseDecoderTest.h"
+
+static void ReadFrame(std::ifstream* file, BufferedData* buf) {
+  // start code of a frame is {0, 0, 0, 1}
+  int zeroCount = 0;
+  char b;
+
+  buf->Clear();
+  for (;;) {
+    file->read(&b, 1);
+    if (file->gcount() != 1) { // end of file
+      return;
+    }
+    if (!buf->PushBack(b)) {
+      FAIL() << "unable to allocate memory";
+    }
+
+    if (buf->Length() <= 4) {
+      continue;
+    }
+
+    if (zeroCount < 3) {
+      zeroCount = b != 0 ? 0 : zeroCount + 1;
+    } else {
+      if (b == 1) {
+        if (file->seekg(-4, file->cur).good()) {
+          buf->SetLength(buf->Length() - 4);
+          return;
+        } else {
+          FAIL() << "unable to seek file";
+        }
+      } else if (b == 0) {
+        zeroCount = 3;
+      } else {
+        zeroCount = 0;
+      }
+    }
+  }
+}
+
+BaseDecoderTest::BaseDecoderTest()
+  : decoder_(NULL), decodeStatus_(OpenFile) {}
+
+void BaseDecoderTest::SetUp() {
+  long rv = CreateDecoder(&decoder_);
+  ASSERT_EQ(0, rv);
+  ASSERT_TRUE(decoder_ != NULL);
+
+  SDecodingParam decParam;
+  memset(&decParam, 0, sizeof(SDecodingParam));
+  decParam.iOutputColorFormat  = videoFormatI420;
+  decParam.uiTargetDqLayer = UCHAR_MAX;
+  decParam.uiEcActiveFlag  = 1;
+  decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
+
+  rv = decoder_->Initialize(&decParam);
+  ASSERT_EQ(0, rv);
+}
+
+void BaseDecoderTest::TearDown() {
+  if (decoder_ != NULL) {
+    decoder_->Uninitialize();
+    DestroyDecoder(decoder_);
+  }
+}
+
+
+void BaseDecoderTest::DecodeFrame(const uint8_t* src, int sliceSize, Callback* cbk) {
+  void* data[3];
+  SBufferInfo bufInfo;
+  memset(data, 0, sizeof(data));
+  memset(&bufInfo, 0, sizeof(SBufferInfo));
+
+  DECODING_STATE rv = decoder_->DecodeFrame2(src, sliceSize, data, &bufInfo);
+  ASSERT_TRUE(rv == dsErrorFree);
+
+  if (bufInfo.iBufferStatus == 1 && cbk != NULL) {
+    const Frame frame = {
+        { // y plane
+            static_cast<uint8_t*>(data[0]),
+            bufInfo.UsrData.sSystemBuffer.iWidth,
+            bufInfo.UsrData.sSystemBuffer.iHeight,
+            bufInfo.UsrData.sSystemBuffer.iStride[0]
+        },
+        { // u plane
+            static_cast<uint8_t*>(data[1]),
+            bufInfo.UsrData.sSystemBuffer.iWidth / 2,
+            bufInfo.UsrData.sSystemBuffer.iHeight / 2,
+            bufInfo.UsrData.sSystemBuffer.iStride[1]
+        },
+        { // v plane
+            static_cast<uint8_t*>(data[2]),
+            bufInfo.UsrData.sSystemBuffer.iWidth / 2,
+            bufInfo.UsrData.sSystemBuffer.iHeight / 2,
+            bufInfo.UsrData.sSystemBuffer.iStride[1]
+        },
+    };
+    cbk->onDecodeFrame(frame);
+  }
+}
+void BaseDecoderTest::DecodeFile(const char* fileName, Callback* cbk) {
+  std::ifstream file(fileName, std::ios::in | std::ios::binary);
+  ASSERT_TRUE(file.is_open());
+
+  BufferedData buf;
+  while (true) {
+    ReadFrame(&file, &buf);
+    if (::testing::Test::HasFatalFailure()) {
+      return;
+    }
+    if (buf.Length() == 0) {
+      break;
+    }
+    DecodeFrame(buf.data(), buf.Length(), cbk);
+    if (::testing::Test::HasFatalFailure()) {
+      return;
+    }
+  }
+
+  int32_t iEndOfStreamFlag = 1;
+  decoder_->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
+
+  // Get pending last frame
+  DecodeFrame(NULL, 0, cbk);
+}
+
+bool BaseDecoderTest::Open(const char* fileName) {
+  if (decodeStatus_ == OpenFile) {
+    file_.open(fileName, std::ios_base::out | std::ios_base::binary);
+    if (file_.is_open()) {
+      decodeStatus_ = Decoding;
+      return true;
+    }
+  }
+  return false;
+}
+
+bool BaseDecoderTest::DecodeNextFrame(Callback* cbk) {
+  switch (decodeStatus_) {
+  case Decoding:
+    ReadFrame(&file_, &buf_);
+    if (::testing::Test::HasFatalFailure()) {
+      return false;
+    }
+    if (buf_.Length() == 0) {
+      decodeStatus_ = EndOfStream;
+      return true;
+    }
+    DecodeFrame(buf_.data(), buf_.Length(), cbk);
+    if (::testing::Test::HasFatalFailure()) {
+      return false;
+    }
+    return true;
+  case EndOfStream: {
+    int32_t iEndOfStreamFlag = 1;
+    decoder_->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
+    DecodeFrame(NULL, 0, cbk);
+    decodeStatus_ = End;
+    break;
+  }
+  case OpenFile:
+  case End:
+    break;
+  }
+  return false;
+}
--- /dev/null
+++ b/test/api/BaseEncoderTest.cpp
@@ -1,0 +1,101 @@
+#include <fstream>
+#include <gtest/gtest.h>
+#include "codec_def.h"
+#include "utils/BufferedData.h"
+#include "utils/FileInputStream.h"
+#include "BaseEncoderTest.h"
+
+static int InitWithParam(ISVCEncoder* encoder, int width,
+    int height, float frameRate, SliceModeEnum sliceMode, bool denoise, int deblock, int layers) {
+  if (SM_SINGLE_SLICE == sliceMode && !denoise && deblock == 1 && layers == 1) {
+    SEncParamBase param;
+    memset (&param, 0, sizeof(SEncParamBase));
+
+    param.fMaxFrameRate = frameRate;
+    param.iPicWidth = width;
+    param.iPicHeight = height;
+    param.iTargetBitrate = 5000000;
+    param.iInputCsp = videoFormatI420;
+
+    return encoder->Initialize(&param);
+  } else {
+    SEncParamExt param;
+    encoder->GetDefaultParams(&param);
+
+    param.fMaxFrameRate = frameRate;
+    param.iPicWidth = width;
+    param.iPicHeight = height;
+    param.iTargetBitrate = 5000000;
+    param.iInputCsp = videoFormatI420;
+    param.bEnableDenoise = denoise;
+    param.iLoopFilterDisableIdc = deblock;
+    param.iSpatialLayerNum = layers;
+
+    for (int i = 0; i < param.iSpatialLayerNum; i++) {
+      param.sSpatialLayers[i].iVideoWidth = width >> (param.iSpatialLayerNum - 1 - i);
+      param.sSpatialLayers[i].iVideoHeight = height >> (param.iSpatialLayerNum - 1 - i);
+      param.sSpatialLayers[i].fFrameRate = frameRate;
+      param.sSpatialLayers[i].iSpatialBitrate = param.iTargetBitrate;
+
+      param.sSpatialLayers[i].sSliceCfg.uiSliceMode = sliceMode;
+    }
+
+    return encoder->InitializeExt(&param);
+  }
+}
+
+BaseEncoderTest::BaseEncoderTest() : encoder_(NULL) {}
+
+void BaseEncoderTest::SetUp() {
+  int rv = CreateSVCEncoder(&encoder_);
+  ASSERT_EQ(0, rv);
+  ASSERT_TRUE(encoder_ != NULL);
+}
+
+void BaseEncoderTest::TearDown() {
+  if (encoder_) {
+    encoder_->Uninitialize();
+    DestroySVCEncoder(encoder_);
+  }
+}
+
+void BaseEncoderTest::EncodeStream(InputStream* in, int width, int height,
+    float frameRate, SliceModeEnum slices, bool denoise, int deblock, int layers, Callback* cbk) {
+  int rv = InitWithParam(encoder_, width, height, frameRate, slices, denoise, deblock, layers);
+  ASSERT_TRUE(rv == cmResultSuccess);
+
+  // I420: 1(Y) + 1/4(U) + 1/4(V)
+  int frameSize = width * height * 3 / 2;
+
+  BufferedData buf;
+  buf.SetLength(frameSize);
+  ASSERT_TRUE(buf.Length() == frameSize);
+
+  SFrameBSInfo info;
+  memset(&info, 0, sizeof(SFrameBSInfo));
+
+  SSourcePicture pic;
+  memset(&pic,0,sizeof(SSourcePicture));
+  pic.iPicWidth = width;
+  pic.iPicHeight = height;
+  pic.iColorFormat = videoFormatI420;
+  pic.iStride[0] = pic.iPicWidth;
+  pic.iStride[1] = pic.iStride[2] = pic.iPicWidth>>1;
+  pic.pData[0] = buf.data();
+  pic.pData[1] = pic.pData[0] + width *height;
+  pic.pData[2] = pic.pData[1] + (width*height>>2);
+  while (in->read(buf.data(), frameSize) == frameSize) {
+    rv = encoder_->EncodeFrame(&pic, &info);
+    ASSERT_TRUE(rv == cmResultSuccess);
+    if (info.eOutputFrameType != videoFrameTypeSkip && cbk != NULL) {
+      cbk->onEncodeFrame(info);
+    }
+  }
+}
+
+void BaseEncoderTest::EncodeFile(const char* fileName, int width, int height,
+    float frameRate, SliceModeEnum slices, bool denoise, int deblock, int layers, Callback* cbk) {
+  FileInputStream fileStream;
+  ASSERT_TRUE(fileStream.Open(fileName));
+  EncodeStream(&fileStream, width, height, frameRate, slices, denoise, deblock, layers, cbk);
+}
--- /dev/null
+++ b/test/api/DataGenerator.cpp
@@ -1,0 +1,66 @@
+#include <string.h>//memset/memcpy
+#include <time.h>
+#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<iHeight;j++) {
+      memcpy(pLocalPointer, pSrcPointer, iWidth*sizeof(uint8_t));
+      pLocalPointer += iStride;
+      pSrcPointer += SRC_FRAME_WIDTH;
+    }
+    return true;
+  }
+  return false;
+}
+
+void RandomPixelDataGenerator( uint8_t* pPointer, int32_t iWidth, int32_t iHeight, int32_t iStride )
+{
+  uint8_t* pLocalPointer = pPointer;
+  for (int32_t j=0;j<iHeight;j++) {
+    for (int32_t i=0;i<iWidth;i++) {
+      pLocalPointer[i] = rand()%256;
+    }
+    pLocalPointer += 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 )
+{
+}
+
--- /dev/null
+++ b/test/api/c_interface_test.c
@@ -1,0 +1,50 @@
+#include "codec_api.h"
+#include <stddef.h>
+
+// Cast to this function type to ignore other parameters.
+typedef int (*Func)(void*);
+#define CALL(p, m) (((Func)((*p)->m))(p))
+// Check if the function return an expected number.
+#define CHECK(n, p, m) check(n, CALL(p, m), #m)
+
+typedef void(*CheckFunc)(int, int, const char*);
+
+void CheckEncoderInterface(ISVCEncoder* p, CheckFunc check) {
+  CHECK(1, p, Initialize);
+  CHECK(2, p, InitializeExt);
+  CHECK(3, p, GetDefaultParams);
+  CHECK(4, p, Uninitialize);
+  CHECK(5, p, EncodeFrame);
+  CHECK(6, p, EncodeParameterSets);
+  CHECK(7, p, PauseFrame);
+  CHECK(8, p, ForceIntraFrame);
+  CHECK(9, p, SetOption);
+  CHECK(10, p, GetOption);
+}
+
+void CheckDecoderInterface(ISVCDecoder* p, CheckFunc check) {
+  CHECK(1, p, Initialize);
+  CHECK(2, p, Uninitialize);
+  CHECK(3, p, DecodeFrame);
+  CHECK(4, p, DecodeFrame2);
+  CHECK(5, p, DecodeFrameEx);
+  CHECK(6, p, SetOption);
+  CHECK(7, p, GetOption);
+}
+
+struct bool_test_struct {
+  char c;
+  bool b;
+};
+
+size_t GetBoolSize(void) {
+  return sizeof(bool);
+}
+
+size_t GetBoolOffset(void) {
+  return offsetof(struct bool_test_struct, b);
+}
+
+size_t GetBoolStructSize(void) {
+  return sizeof(struct bool_test_struct);
+}
--- /dev/null
+++ b/test/api/cpp_interface_test.cpp
@@ -1,0 +1,129 @@
+#include <gtest/gtest.h>
+#include "codec_api.h"
+#include <stddef.h>
+
+static void CheckFunctionOrder(int expect, int actual, const char* name) {
+  EXPECT_EQ(expect, actual) << "Wrong function order: " << name;
+}
+
+typedef void(*CheckFunc)(int, int, const char*);
+extern "C" void CheckEncoderInterface(ISVCEncoder* p, CheckFunc);
+extern "C" void CheckDecoderInterface(ISVCDecoder* p, CheckFunc);
+extern "C" size_t GetBoolSize(void);
+extern "C" size_t GetBoolOffset(void);
+extern "C" size_t GetBoolStructSize(void);
+
+// Store the 'this' pointer to verify 'this' is received as expected from C code.
+static void* gThis;
+
+/**
+ * Return a unique number for each virtual function so that we are able to
+ * check if the order of functions in the virtual table is as expected.
+ */
+struct SVCEncoderImpl : public ISVCEncoder {
+  virtual ~SVCEncoderImpl() {}
+  virtual int EXTAPI Initialize(const SEncParamBase* pParam) {
+    EXPECT_TRUE(gThis == this);
+    return 1;
+  }
+  virtual int EXTAPI InitializeExt(const SEncParamExt* pParam) {
+    EXPECT_TRUE(gThis == this);
+    return 2;
+  }
+  virtual int EXTAPI GetDefaultParams(SEncParamExt* pParam) {
+    EXPECT_TRUE(gThis == this);
+    return 3;
+  }
+  virtual int EXTAPI Uninitialize() {
+    EXPECT_TRUE(gThis == this);
+    return 4;
+  }
+  virtual int EXTAPI EncodeFrame(const SSourcePicture* kpSrcPic,
+      SFrameBSInfo* pBsInfo) {
+    EXPECT_TRUE(gThis == this);
+    return 5;
+  }
+  virtual int EXTAPI EncodeParameterSets(SFrameBSInfo* pBsInfo) {
+    EXPECT_TRUE(gThis == this);
+    return 6;
+  }
+  virtual int EXTAPI PauseFrame(const SSourcePicture* kpSrcPic,
+      SFrameBSInfo* pBsInfo) {
+    EXPECT_TRUE(gThis == this);
+    return 7;
+  }
+  virtual int EXTAPI ForceIntraFrame(bool bIDR) {
+    EXPECT_TRUE(gThis == this);
+    return 8;
+  }
+  virtual int EXTAPI SetOption(ENCODER_OPTION eOptionId, void* pOption) {
+    EXPECT_TRUE(gThis == this);
+    return 9;
+  }
+  virtual int EXTAPI GetOption(ENCODER_OPTION eOptionId, void* pOption) {
+    EXPECT_TRUE(gThis == this);
+    return 10;
+  }
+};
+
+struct SVCDecoderImpl : public ISVCDecoder {
+  virtual ~SVCDecoderImpl() {}
+  virtual long EXTAPI Initialize(const SDecodingParam* pParam) {
+    EXPECT_TRUE(gThis == this);
+    return 1;
+  }
+  virtual long EXTAPI Uninitialize() {
+    EXPECT_TRUE(gThis == this);
+    return 2;
+  }
+  virtual DECODING_STATE EXTAPI DecodeFrame(const unsigned char* pSrc,
+      const int iSrcLen, unsigned char** ppDst, int* pStride,
+      int& iWidth, int& iHeight) {
+    EXPECT_TRUE(gThis == this);
+    return static_cast<DECODING_STATE>(3);
+  }
+  virtual DECODING_STATE EXTAPI DecodeFrame2(const unsigned char* pSrc,
+      const int iSrcLen, void** ppDst, SBufferInfo* pDstInfo) {
+    EXPECT_TRUE(gThis == this);
+    return static_cast<DECODING_STATE>(4);
+  }
+  virtual DECODING_STATE EXTAPI DecodeFrameEx(const unsigned char* pSrc,
+      const int iSrcLen, unsigned char* pDst, int iDstStride,
+      int& iDstLen, int& iWidth, int& iHeight, int& iColorFormat) {
+    EXPECT_TRUE(gThis == this);
+    return static_cast<DECODING_STATE>(5);
+  }
+  virtual long EXTAPI SetOption (DECODER_OPTION eOptionId, void* pOption) {
+    EXPECT_TRUE(gThis == this);
+    return 6;
+  }
+  virtual long EXTAPI GetOption (DECODER_OPTION eOptionId, void* pOption) {
+    EXPECT_TRUE(gThis == this);
+    return 7;
+  }
+};
+
+TEST(ISVCEncoderTest, CheckFunctionOrder) {
+  SVCEncoderImpl* p = new SVCEncoderImpl;
+  gThis = p;
+  CheckEncoderInterface(p, CheckFunctionOrder);
+  delete p;
+}
+
+TEST(ISVCDecoderTest, CheckFunctionOrder) {
+  SVCDecoderImpl* p = new SVCDecoderImpl;
+  gThis = p;
+  CheckDecoderInterface(p, CheckFunctionOrder);
+  delete p;
+}
+
+struct bool_test_struct {
+  char c;
+  bool b;
+};
+
+TEST(ISVCDecoderEncoderTest, CheckCAbi) {
+  EXPECT_EQ(sizeof(bool), GetBoolSize()) << "Wrong size of bool type";
+  EXPECT_EQ(offsetof(bool_test_struct, b), GetBoolOffset()) << "Wrong alignment of bool in a struct";
+  EXPECT_EQ(sizeof(bool_test_struct), GetBoolStructSize()) << "Wrong size of struct with a bool";
+}
--- /dev/null
+++ b/test/api/decode_encode_test.cpp
@@ -1,0 +1,112 @@
+#include <gtest/gtest.h>
+#include "codec_def.h"
+#include "utils/HashFunctions.h"
+#include "utils/BufferedData.h"
+#include "utils/InputStream.h"
+#include "BaseDecoderTest.h"
+#include "BaseEncoderTest.h"
+
+static void UpdateHashFromFrame(const SFrameBSInfo& info, SHA1Context* ctx) {
+  for (int i = 0; i < info.iLayerNum; ++i) {
+    const SLayerBSInfo& layerInfo = info.sLayerInfo[i];
+    int layerSize = 0;
+    for (int j = 0; j < layerInfo.iNalCount; ++j) {
+      layerSize += layerInfo.iNalLengthInByte[j];
+    }
+    SHA1Input(ctx, layerInfo.pBsBuf, layerSize);
+  }
+}
+
+static void WritePlaneBuffer(BufferedData* buf, const uint8_t* plane,
+    int width, int height, int stride) {
+  for (int i = 0; i < height; i++) {
+    if (!buf->PushBack(plane, width)) {
+      FAIL() << "unable to allocate memory";
+    }
+    plane += stride;
+  }
+}
+
+struct DecodeEncodeFileParam {
+  const char* fileName;
+  const char* hashStr;
+  int width;
+  int height;
+  float frameRate;
+};
+
+class DecodeEncodeTest : public ::testing::TestWithParam<DecodeEncodeFileParam>,
+    public BaseDecoderTest, public BaseDecoderTest::Callback,
+    public BaseEncoderTest , public BaseEncoderTest::Callback,
+    public InputStream {
+ public:
+  virtual void SetUp() {
+    BaseDecoderTest::SetUp();
+    if (HasFatalFailure()) {
+      return;
+    }
+    BaseEncoderTest::SetUp();
+    if (HasFatalFailure()) {
+      return;
+    }
+    SHA1Reset(&ctx_);
+  }
+
+  virtual void TearDown() {
+    BaseDecoderTest::TearDown();
+    BaseEncoderTest::TearDown();
+  }
+
+  virtual void onDecodeFrame(const Frame& frame) {
+    const Plane& y = frame.y;
+    const Plane& u = frame.u;
+    const Plane& v = frame.v;
+    WritePlaneBuffer(&buf_, y.data, y.width, y.height, y.stride);
+    WritePlaneBuffer(&buf_, u.data, u.width, u.height, u.stride);
+    WritePlaneBuffer(&buf_, v.data, v.width, v.height, v.stride);
+  }
+
+  virtual void onEncodeFrame(const SFrameBSInfo& frameInfo) {
+    UpdateHashFromFrame(frameInfo, &ctx_);
+  }
+
+  virtual int read(void* ptr, size_t len) {
+    while (buf_.Length() < len) {
+      bool hasNext = DecodeNextFrame(this);
+      if (HasFatalFailure()) {
+        return -1;
+      }
+      if (!hasNext) {
+        if (buf_.Length() == 0) {
+          return -1;
+        }
+        break;
+      }
+    }
+    return buf_.PopFront(static_cast<uint8_t*>(ptr), len);
+  }
+
+ protected:
+  SHA1Context ctx_;
+  BufferedData buf_;
+};
+
+TEST_P(DecodeEncodeTest, CompareOutput) {
+  DecodeEncodeFileParam p = GetParam();
+
+  ASSERT_TRUE(Open(p.fileName));
+  EncodeStream(this, p.width, p.height, p.frameRate, SM_SINGLE_SLICE, false, 1, 1, this);
+  unsigned char digest[SHA_DIGEST_LENGTH];
+  SHA1Result(&ctx_, digest);
+  if (!HasFatalFailure()) {
+    CompareHash(digest, p.hashStr);
+  }
+}
+
+static const DecodeEncodeFileParam kFileParamArray[] = {
+  {"res/test_vd_1d.264", "c04a5978eb715837c29463e79b6598a05136829f", 320, 192, 12.0f},
+  {"res/test_vd_rc.264", "40d8eb5a54d358c663f836c689a158c326de4b1c", 320, 192, 12.0f},
+};
+
+INSTANTIATE_TEST_CASE_P(DecodeEncodeFile, DecodeEncodeTest,
+    ::testing::ValuesIn(kFileParamArray));
--- /dev/null
+++ b/test/api/decoder_test.cpp
@@ -1,0 +1,100 @@
+#include <gtest/gtest.h>
+#include "utils/HashFunctions.h"
+#include "BaseDecoderTest.h"
+
+static void UpdateHashFromPlane(SHA1Context* ctx, const uint8_t* plane,
+    int width, int height, int stride) {
+  for (int i = 0; i < height; i++) {
+    SHA1Input(ctx, plane, width);
+    plane += stride;
+  }
+}
+
+
+class DecoderInitTest : public ::testing::Test, public BaseDecoderTest {
+ public:
+  virtual void SetUp() {
+    BaseDecoderTest::SetUp();
+  }
+  virtual void TearDown() {
+    BaseDecoderTest::TearDown();
+  }
+};
+
+TEST_F(DecoderInitTest, JustInit) {}
+
+struct FileParam {
+  const char* fileName;
+  const char* hashStr;
+};
+
+class DecoderOutputTest : public ::testing::WithParamInterface<FileParam>,
+    public DecoderInitTest, public BaseDecoderTest::Callback {
+ public:
+  virtual void SetUp() {
+    DecoderInitTest::SetUp();
+    if (HasFatalFailure()) {
+      return;
+    }
+    SHA1Reset(&ctx_);
+  }
+  virtual void onDecodeFrame(const Frame& frame) {
+    const Plane& y = frame.y;
+    const Plane& u = frame.u;
+    const Plane& v = frame.v;
+    UpdateHashFromPlane(&ctx_, y.data, y.width, y.height, y.stride);
+    UpdateHashFromPlane(&ctx_, u.data, u.width, u.height, u.stride);
+    UpdateHashFromPlane(&ctx_, v.data, v.width, v.height, v.stride);
+  }
+ protected:
+  SHA1Context ctx_;
+};
+
+TEST_P(DecoderOutputTest, CompareOutput) {
+  FileParam p = GetParam();
+  DecodeFile(p.fileName, this);
+
+  unsigned char digest[SHA_DIGEST_LENGTH];
+  SHA1Result(&ctx_, digest);
+  if (!HasFatalFailure()) {
+    CompareHash(digest, p.hashStr);
+  }
+}
+
+static const FileParam kFileParamArray[] = {
+  {"res/test_vd_1d.264", "5827d2338b79ff82cd091c707823e466197281d3"},
+  {"res/test_vd_rc.264", "eea02e97bfec89d0418593a8abaaf55d02eaa1ca"},
+  {"res/Static.264", "91dd4a7a796805b2cd015cae8fd630d96c663f42"},
+  {"res/BA1_FT_C.264", "418d152fb85709b6f172799dcb239038df437cfa"},
+  {"res/BA1_Sony_D.jsv", "d94b5ceed5686a03ea682b53d415dee999d27eb6"}, 
+  {"res/BAMQ1_JVC_C.264", "613cf662c23e5d9e1d7da7fe880a3c427411d171"},
+  {"res/BAMQ2_JVC_C.264", "11bcf3713f520e606a8326d37e00e5fd6c9fd4a0"},
+  {"res/BA_MW_D.264", "afd7a9765961ca241bb4bdf344b31397bec7465a"},
+  {"res/BANM_MW_D.264", "92d924a857a1a7d7d9b224eaa3887830f15dee7f"},
+  {"res/BASQP1_Sony_C.jsv", "3986c8c9d2876d2f0748b925101b152c6ec8b811"},
+  {"res/CI1_FT_B.264", "cbfec15e17a504678b19a1191992131c92a1ac26"},
+  {"res/CI_MW_D.264", "289f29a103c8d95adf2909c646466904be8b06d7"},
+  {"res/CVFC1_Sony_C.jsv", "4641abd7419a5580b97f16e83fd1d566339229d0"}, 
+  {"res/CVPCMNL1_SVA_C.264", "c2b0d964de727c64b9fccb58f63b567c82bda95a"},
+  {"res/LS_SVA_D.264", "72118f4d1674cf14e58bed7e67cb3aeed3df62b9"},
+  {"res/MIDR_MW_D.264", "9467030f4786f75644bf06a7fc809c36d1959827"},
+  {"res/MPS_MW_A.264", "67f1cfbef0e8025ed60dedccf8d9558d0636be5f"},
+  {"res/MR1_BT_A.h264", "6e585f8359667a16b03e5f49a06f5ceae8d991e0"},
+  {"res/MR1_MW_A.264", "d9e2bf34e9314dcc171ddaea2c5015d0421479f2"},
+  {"res/MR2_MW_A.264", "628b1d4eff04c2d277f7144e23484957dad63cbe"},
+  {"res/MR2_TANDBERG_E.264", "74d618bc7d9d41998edf4c85d51aa06111db6609"},
+  {"res/NL1_Sony_D.jsv", "e401e30669938443c2f02522fd4d5aa1382931a0"},
+  {"res/NLMQ1_JVC_C.264", "f3265c6ddf8db1b2bf604d8a2954f75532e28cda"},
+  {"res/NLMQ2_JVC_C.264", "350ae86ef9ba09390d63a09b7f9ff54184109ca8"},
+  {"res/NRF_MW_E.264", "20732198c04cd2591350a361e4510892f6eed3f0"},
+  {"res/SVA_BA1_B.264", "c4543b24823b16c424c673616c36c7f537089b2d"},
+  {"res/SVA_BA2_D.264", "98ff2d67860462d8d8bcc9352097c06cc401d97e"},
+  {"res/SVA_Base_B.264", "91f514d81cd33de9f6fbf5dbefdb189cc2e7ecf4"},
+  {"res/SVA_CL1_E.264", "4fe09ab6cdc965ea10a20f1d6dd38aca954412bb"},
+  {"res/SVA_FM1_E.264", "fad08c4ff7cf2307b6579853d0f4652fc26645d3"},
+  {"res/SVA_NL1_B.264", "6d63f72a0c0d833b1db0ba438afff3b4180fb3e6"},
+  {"res/SVA_NL2_E.264", "70453ef8097c94dd190d6d2d1d5cb83c67e66238"}
+};
+
+INSTANTIATE_TEST_CASE_P(DecodeFile, DecoderOutputTest,
+    ::testing::ValuesIn(kFileParamArray));
--- /dev/null
+++ b/test/api/encoder_test.cpp
@@ -1,0 +1,101 @@
+#include <gtest/gtest.h>
+#include "utils/HashFunctions.h"
+#include "BaseEncoderTest.h"
+
+static void UpdateHashFromFrame(const SFrameBSInfo& info, SHA1Context* ctx) {
+  for (int i = 0; i < info.iLayerNum; ++i) {
+    const SLayerBSInfo& layerInfo = info.sLayerInfo[i];
+    int layerSize = 0;
+    for (int j = 0; j < layerInfo.iNalCount; ++j) {
+      layerSize += layerInfo.iNalLengthInByte[j];
+    }
+    SHA1Input(ctx, layerInfo.pBsBuf, layerSize);
+  }
+}
+
+class EncoderInitTest : public ::testing::Test, public BaseEncoderTest {
+ public:
+  virtual void SetUp() {
+    BaseEncoderTest::SetUp();
+  }
+  virtual void TearDown() {
+    BaseEncoderTest::TearDown();
+  }
+};
+
+TEST_F(EncoderInitTest, JustInit) {}
+
+struct EncodeFileParam {
+  const char* fileName;
+  const char* hashStr;
+  int width;
+  int height;
+  float frameRate;
+  SliceModeEnum slices;
+  bool denoise;
+  int deblocking;
+  int layers;
+};
+
+class EncoderOutputTest : public ::testing::WithParamInterface<EncodeFileParam>,
+    public EncoderInitTest , public BaseEncoderTest::Callback {
+ public:
+  virtual void SetUp() {
+    EncoderInitTest::SetUp();
+    if (HasFatalFailure()) {
+      return;
+    }
+    SHA1Reset(&ctx_);
+  }
+  virtual void onEncodeFrame(const SFrameBSInfo& frameInfo) {
+    UpdateHashFromFrame(frameInfo, &ctx_);
+  }
+ protected:
+  SHA1Context ctx_;
+};
+
+
+TEST_P(EncoderOutputTest, CompareOutput) {
+  EncodeFileParam p = GetParam();
+  EncodeFile(p.fileName, p.width, p.height, p.frameRate, p.slices, p.denoise, p.deblocking, p.layers, this);
+
+  unsigned char digest[SHA_DIGEST_LENGTH];
+  SHA1Result(&ctx_, digest);
+  if (!HasFatalFailure()) {
+    CompareHash(digest, p.hashStr);
+  }
+}
+
+static const EncodeFileParam kFileParamArray[] = {
+  {
+      "res/CiscoVT2people_320x192_12fps.yuv",
+      "06441376891cbc237a36e59b62131cd94ff9cb19", 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1, 1
+  },
+  {
+      "res/CiscoVT2people_160x96_6fps.yuv",
+      "4f3759fc44125b27a179ebff158dbba9e431bd0b", 160, 96, 6.0f, SM_SINGLE_SLICE, false, 1, 1
+  },
+  {
+      "res/Static_152_100.yuv",
+      "af5c6a41b567ce1b2cb6fd427f4379473d3b829f", 152, 100, 6.0f, SM_SINGLE_SLICE, false, 1, 1
+  },
+  {
+      "res/CiscoVT2people_320x192_12fps.yuv",
+      "be0079b022b18fdce04570db24e4327ca26a0ecb", 320, 192, 12.0f, SM_ROWMB_SLICE, false, 1, 1 // One slice per MB row
+  },
+  {
+      "res/CiscoVT2people_320x192_12fps.yuv",
+      "f4649601ca15f9693671d7e161e9daa8efd3a7a1", 320, 192, 12.0f, SM_SINGLE_SLICE, true, 1, 1
+  },
+  {
+      "res/CiscoVT2people_320x192_12fps.yuv",
+      "e4bcd744d2e6f885f6c0dbe5d52818ba64d986d9", 320, 192, 12.0f, SM_SINGLE_SLICE, false, 0, 1
+  },
+  {
+      "res/CiscoVT2people_320x192_12fps.yuv",
+      "ba81a0f1a14214e6d3c7f1608991b3ac97789370", 320, 192, 12.0f, SM_SINGLE_SLICE, false, 0, 2
+  },
+};
+
+INSTANTIATE_TEST_CASE_P(EncodeFile, EncoderOutputTest,
+    ::testing::ValuesIn(kFileParamArray));
--- /dev/null
+++ b/test/api/sha1.c
@@ -1,0 +1,399 @@
+/*!
+ * \copy
+ *     Copyright (c)  1998, 2009 Paul E. Jones <[email protected]>
+ *     All rights reserved.
+ *
+ *     Redistribution and use in source and binary forms, with or without
+ *     modification, are permitted provided that the following conditions
+ *     are met:
+ *
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in
+ *          the documentation and/or other materials provided with the
+ *          distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *     POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ *  Description:
+ *      This file implements the Secure Hashing Standard as defined
+ *      in FIPS PUB 180-1 published April 17, 1995.
+ *
+ *      The Secure Hashing Standard, which uses the Secure Hashing
+ *      Algorithm (SHA), produces a 160-bit message digest for a
+ *      given data stream.  In theory, it is highly improbable that
+ *      two messages will produce the same message digest.  Therefore,
+ *      this algorithm can serve as a means of providing a "fingerprint"
+ *      for a message.
+ *
+ *  Portability Issues:
+ *      SHA-1 is defined in terms of 32-bit "words".  This code was
+ *      written with the expectation that the processor has at least
+ *      a 32-bit machine word size.  If the machine word size is larger,
+ *      the code should still function properly.  One caveat to that
+ *      is that the input functions taking characters and character
+ *      arrays assume that only 8 bits of information are stored in each
+ *      character.
+ *
+ *  Caveats:
+ *      SHA-1 is designed to work with messages less than 2^64 bits
+ *      long. Although SHA-1 allows a message digest to be generated for
+ *      messages of any number of bits less than 2^64, this
+ *      implementation only works with messages with a length that is a
+ *      multiple of the size of an 8-bit character.
+ *
+ */
+
+#include "sha1.h"
+
+/*
+ *  Define the circular shift macro
+ */
+#define SHA1CircularShift(bits,word) \
+                ((((word) << (bits)) & 0xFFFFFFFF) | \
+                ((word) >> (32-(bits))))
+
+/* Function prototypes */
+void SHA1ProcessMessageBlock(SHA1Context *);
+void SHA1PadMessage(SHA1Context *);
+
+/*
+ *  SHA1Reset
+ *
+ *  Description:
+ *      This function will initialize the SHA1Context in preparation
+ *      for computing a new message digest.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The context to reset.
+ *
+ *  Returns:
+ *      Nothing.
+ *
+ *  Comments:
+ *
+ */
+void SHA1Reset(SHA1Context *context)
+{
+    context->Length_Low             = 0;
+    context->Length_High            = 0;
+    context->Message_Block_Index    = 0;
+
+    context->Message_Digest[0]      = 0x67452301;
+    context->Message_Digest[1]      = 0xEFCDAB89;
+    context->Message_Digest[2]      = 0x98BADCFE;
+    context->Message_Digest[3]      = 0x10325476;
+    context->Message_Digest[4]      = 0xC3D2E1F0;
+
+    context->Computed   = 0;
+    context->Corrupted  = 0;
+}
+
+/*
+ *  SHA1Result
+ *
+ *  Description:
+ *      This function will return the 160-bit message digest into the
+ *      digest array provided as a parameter.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The context to use to calculate the SHA-1 hash.
+ *      digest: [out]
+ *          An array of characters where the digest is written.
+ *
+ *  Returns:
+ *      1 if successful, 0 if it failed.
+ *
+ *  Comments:
+ *
+ */
+int SHA1Result(SHA1Context *context, unsigned char *digest)
+{
+    int i;
+
+    if (context->Corrupted)
+    {
+        return 0;
+    }
+
+    if (!context->Computed)
+    {
+        SHA1PadMessage(context);
+        context->Computed = 1;
+    }
+
+    for (i = 0; i < SHA_DIGEST_LENGTH; i++)
+        digest[i] = context->Message_Digest[i / 4] >> (8 * (3 - (i % 4)));
+
+    return 1;
+}
+
+/*
+ *  SHA1Input
+ *
+ *  Description:
+ *      This function accepts an array of octets as the next portion of
+ *      the message.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The SHA-1 context to update
+ *      message_array: [in]
+ *          An array of characters representing the next portion of the
+ *          message.
+ *      length: [in]
+ *          The length of the message in message_array
+ *
+ *  Returns:
+ *      Nothing.
+ *
+ *  Comments:
+ *
+ */
+void SHA1Input(     SHA1Context         *context,
+                    const unsigned char *message_array,
+                    unsigned            length)
+{
+    if (!length)
+    {
+        return;
+    }
+
+    if (context->Computed || context->Corrupted)
+    {
+        context->Corrupted = 1;
+        return;
+    }
+
+    while(length-- && !context->Corrupted)
+    {
+        context->Message_Block[context->Message_Block_Index++] =
+                                                (*message_array & 0xFF);
+
+        context->Length_Low += 8;
+        /* Force it to 32 bits */
+        context->Length_Low &= 0xFFFFFFFF;
+        if (context->Length_Low == 0)
+        {
+            context->Length_High++;
+            /* Force it to 32 bits */
+            context->Length_High &= 0xFFFFFFFF;
+            if (context->Length_High == 0)
+            {
+                /* Message is too long */
+                context->Corrupted = 1;
+            }
+        }
+
+        if (context->Message_Block_Index == 64)
+        {
+            SHA1ProcessMessageBlock(context);
+        }
+
+        message_array++;
+    }
+}
+
+/*
+ *  SHA1ProcessMessageBlock
+ *
+ *  Description:
+ *      This function will process the next 512 bits of the message
+ *      stored in the Message_Block array.
+ *
+ *  Parameters:
+ *      None.
+ *
+ *  Returns:
+ *      Nothing.
+ *
+ *  Comments:
+ *      Many of the variable names in the SHAContext, especially the
+ *      single character names, were used because those were the names
+ *      used in the publication.
+ *
+ *
+ */
+void SHA1ProcessMessageBlock(SHA1Context *context)
+{
+    const unsigned K[] =            /* Constants defined in SHA-1   */
+    {
+        0x5A827999,
+        0x6ED9EBA1,
+        0x8F1BBCDC,
+        0xCA62C1D6
+    };
+    int         t;                  /* Loop counter                 */
+    unsigned    temp;               /* Temporary word value         */
+    unsigned    W[80];              /* Word sequence                */
+    unsigned    A, B, C, D, E;      /* Word buffers                 */
+
+    /*
+     *  Initialize the first 16 words in the array W
+     */
+    for(t = 0; t < 16; t++)
+    {
+        W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
+        W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
+        W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
+        W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
+    }
+
+    for(t = 16; t < 80; t++)
+    {
+       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+    }
+
+    A = context->Message_Digest[0];
+    B = context->Message_Digest[1];
+    C = context->Message_Digest[2];
+    D = context->Message_Digest[3];
+    E = context->Message_Digest[4];
+
+    for(t = 0; t < 20; t++)
+    {
+        temp =  SHA1CircularShift(5,A) +
+                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
+        temp &= 0xFFFFFFFF;
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    for(t = 20; t < 40; t++)
+    {
+        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
+        temp &= 0xFFFFFFFF;
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    for(t = 40; t < 60; t++)
+    {
+        temp = SHA1CircularShift(5,A) +
+               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
+        temp &= 0xFFFFFFFF;
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    for(t = 60; t < 80; t++)
+    {
+        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
+        temp &= 0xFFFFFFFF;
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    context->Message_Digest[0] =
+                        (context->Message_Digest[0] + A) & 0xFFFFFFFF;
+    context->Message_Digest[1] =
+                        (context->Message_Digest[1] + B) & 0xFFFFFFFF;
+    context->Message_Digest[2] =
+                        (context->Message_Digest[2] + C) & 0xFFFFFFFF;
+    context->Message_Digest[3] =
+                        (context->Message_Digest[3] + D) & 0xFFFFFFFF;
+    context->Message_Digest[4] =
+                        (context->Message_Digest[4] + E) & 0xFFFFFFFF;
+
+    context->Message_Block_Index = 0;
+}
+
+/*
+ *  SHA1PadMessage
+ *
+ *  Description:
+ *      According to the standard, the message must be padded to an even
+ *      512 bits.  The first padding bit must be a '1'.  The last 64
+ *      bits represent the length of the original message.  All bits in
+ *      between should be 0.  This function will pad the message
+ *      according to those rules by filling the Message_Block array
+ *      accordingly.  It will also call SHA1ProcessMessageBlock()
+ *      appropriately.  When it returns, it can be assumed that the
+ *      message digest has been computed.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The context to pad
+ *
+ *  Returns:
+ *      Nothing.
+ *
+ *  Comments:
+ *
+ */
+void SHA1PadMessage(SHA1Context *context)
+{
+    /*
+     *  Check to see if the current message block is too small to hold
+     *  the initial padding bits and length.  If so, we will pad the
+     *  block, process it, and then continue padding into a second
+     *  block.
+     */
+    if (context->Message_Block_Index > 55)
+    {
+        context->Message_Block[context->Message_Block_Index++] = 0x80;
+        while(context->Message_Block_Index < 64)
+        {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
+
+        SHA1ProcessMessageBlock(context);
+
+        while(context->Message_Block_Index < 56)
+        {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
+    }
+    else
+    {
+        context->Message_Block[context->Message_Block_Index++] = 0x80;
+        while(context->Message_Block_Index < 56)
+        {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
+    }
+
+    /*
+     *  Store the message length as the last 8 octets
+     */
+    context->Message_Block[56] = (context->Length_High >> 24) & 0xFF;
+    context->Message_Block[57] = (context->Length_High >> 16) & 0xFF;
+    context->Message_Block[58] = (context->Length_High >> 8) & 0xFF;
+    context->Message_Block[59] = (context->Length_High) & 0xFF;
+    context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF;
+    context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF;
+    context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF;
+    context->Message_Block[63] = (context->Length_Low) & 0xFF;
+
+    SHA1ProcessMessageBlock(context);
+}
--- /dev/null
+++ b/test/api/simple_test.cpp
@@ -1,0 +1,7 @@
+#include <gtest/gtest.h>
+
+int main (int argc, char** argv) {
+  testing::InitGoogleTest (&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
--- /dev/null
+++ b/test/api/targets.mk
@@ -1,0 +1,26 @@
+API_TEST_SRCDIR=test/api
+API_TEST_CPP_SRCS=\
+	$(API_TEST_SRCDIR)/BaseDecoderTest.cpp\
+	$(API_TEST_SRCDIR)/BaseEncoderTest.cpp\
+	$(API_TEST_SRCDIR)/cpp_interface_test.cpp\
+	$(API_TEST_SRCDIR)/DataGenerator.cpp\
+	$(API_TEST_SRCDIR)/decode_encode_test.cpp\
+	$(API_TEST_SRCDIR)/decoder_test.cpp\
+	$(API_TEST_SRCDIR)/encoder_test.cpp\
+	$(API_TEST_SRCDIR)/simple_test.cpp\
+
+API_TEST_OBJS += $(API_TEST_CPP_SRCS:.cpp=.$(OBJ))
+
+API_TEST_C_SRCS=\
+	$(API_TEST_SRCDIR)/c_interface_test.c\
+	$(API_TEST_SRCDIR)/sha1.c\
+
+API_TEST_OBJS += $(API_TEST_C_SRCS:.c=.$(OBJ))
+
+OBJS += $(API_TEST_OBJS)
+$(API_TEST_SRCDIR)/%.$(OBJ): $(API_TEST_SRCDIR)/%.cpp
+	$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(API_TEST_CFLAGS) $(API_TEST_INCLUDES) -c $(CXX_O) $<
+
+$(API_TEST_SRCDIR)/%.$(OBJ): $(API_TEST_SRCDIR)/%.c
+	$(QUIET_CC)$(CC) $(CFLAGS) $(INCLUDES) $(API_TEST_CFLAGS) $(API_TEST_INCLUDES) -c $(CXX_O) $<
+
--- a/test/c_interface_test.c
+++ /dev/null
@@ -1,50 +1,0 @@
-#include "codec_api.h"
-#include <stddef.h>
-
-// Cast to this function type to ignore other parameters.
-typedef int (*Func)(void*);
-#define CALL(p, m) (((Func)((*p)->m))(p))
-// Check if the function return an expected number.
-#define CHECK(n, p, m) check(n, CALL(p, m), #m)
-
-typedef void(*CheckFunc)(int, int, const char*);
-
-void CheckEncoderInterface(ISVCEncoder* p, CheckFunc check) {
-  CHECK(1, p, Initialize);
-  CHECK(2, p, InitializeExt);
-  CHECK(3, p, GetDefaultParams);
-  CHECK(4, p, Uninitialize);
-  CHECK(5, p, EncodeFrame);
-  CHECK(6, p, EncodeParameterSets);
-  CHECK(7, p, PauseFrame);
-  CHECK(8, p, ForceIntraFrame);
-  CHECK(9, p, SetOption);
-  CHECK(10, p, GetOption);
-}
-
-void CheckDecoderInterface(ISVCDecoder* p, CheckFunc check) {
-  CHECK(1, p, Initialize);
-  CHECK(2, p, Uninitialize);
-  CHECK(3, p, DecodeFrame);
-  CHECK(4, p, DecodeFrame2);
-  CHECK(5, p, DecodeFrameEx);
-  CHECK(6, p, SetOption);
-  CHECK(7, p, GetOption);
-}
-
-struct bool_test_struct {
-  char c;
-  bool b;
-};
-
-size_t GetBoolSize(void) {
-  return sizeof(bool);
-}
-
-size_t GetBoolOffset(void) {
-  return offsetof(struct bool_test_struct, b);
-}
-
-size_t GetBoolStructSize(void) {
-  return sizeof(struct bool_test_struct);
-}
--- a/test/cpp_interface_test.cpp
+++ /dev/null
@@ -1,129 +1,0 @@
-#include <gtest/gtest.h>
-#include "codec_api.h"
-#include <stddef.h>
-
-static void CheckFunctionOrder(int expect, int actual, const char* name) {
-  EXPECT_EQ(expect, actual) << "Wrong function order: " << name;
-}
-
-typedef void(*CheckFunc)(int, int, const char*);
-extern "C" void CheckEncoderInterface(ISVCEncoder* p, CheckFunc);
-extern "C" void CheckDecoderInterface(ISVCDecoder* p, CheckFunc);
-extern "C" size_t GetBoolSize(void);
-extern "C" size_t GetBoolOffset(void);
-extern "C" size_t GetBoolStructSize(void);
-
-// Store the 'this' pointer to verify 'this' is received as expected from C code.
-static void* gThis;
-
-/**
- * Return a unique number for each virtual function so that we are able to
- * check if the order of functions in the virtual table is as expected.
- */
-struct SVCEncoderImpl : public ISVCEncoder {
-  virtual ~SVCEncoderImpl() {}
-  virtual int EXTAPI Initialize(const SEncParamBase* pParam) {
-    EXPECT_TRUE(gThis == this);
-    return 1;
-  }
-  virtual int EXTAPI InitializeExt(const SEncParamExt* pParam) {
-    EXPECT_TRUE(gThis == this);
-    return 2;
-  }
-  virtual int EXTAPI GetDefaultParams(SEncParamExt* pParam) {
-    EXPECT_TRUE(gThis == this);
-    return 3;
-  }
-  virtual int EXTAPI Uninitialize() {
-    EXPECT_TRUE(gThis == this);
-    return 4;
-  }
-  virtual int EXTAPI EncodeFrame(const SSourcePicture* kpSrcPic,
-      SFrameBSInfo* pBsInfo) {
-    EXPECT_TRUE(gThis == this);
-    return 5;
-  }
-  virtual int EXTAPI EncodeParameterSets(SFrameBSInfo* pBsInfo) {
-    EXPECT_TRUE(gThis == this);
-    return 6;
-  }
-  virtual int EXTAPI PauseFrame(const SSourcePicture* kpSrcPic,
-      SFrameBSInfo* pBsInfo) {
-    EXPECT_TRUE(gThis == this);
-    return 7;
-  }
-  virtual int EXTAPI ForceIntraFrame(bool bIDR) {
-    EXPECT_TRUE(gThis == this);
-    return 8;
-  }
-  virtual int EXTAPI SetOption(ENCODER_OPTION eOptionId, void* pOption) {
-    EXPECT_TRUE(gThis == this);
-    return 9;
-  }
-  virtual int EXTAPI GetOption(ENCODER_OPTION eOptionId, void* pOption) {
-    EXPECT_TRUE(gThis == this);
-    return 10;
-  }
-};
-
-struct SVCDecoderImpl : public ISVCDecoder {
-  virtual ~SVCDecoderImpl() {}
-  virtual long EXTAPI Initialize(const SDecodingParam* pParam) {
-    EXPECT_TRUE(gThis == this);
-    return 1;
-  }
-  virtual long EXTAPI Uninitialize() {
-    EXPECT_TRUE(gThis == this);
-    return 2;
-  }
-  virtual DECODING_STATE EXTAPI DecodeFrame(const unsigned char* pSrc,
-      const int iSrcLen, unsigned char** ppDst, int* pStride,
-      int& iWidth, int& iHeight) {
-    EXPECT_TRUE(gThis == this);
-    return static_cast<DECODING_STATE>(3);
-  }
-  virtual DECODING_STATE EXTAPI DecodeFrame2(const unsigned char* pSrc,
-      const int iSrcLen, void** ppDst, SBufferInfo* pDstInfo) {
-    EXPECT_TRUE(gThis == this);
-    return static_cast<DECODING_STATE>(4);
-  }
-  virtual DECODING_STATE EXTAPI DecodeFrameEx(const unsigned char* pSrc,
-      const int iSrcLen, unsigned char* pDst, int iDstStride,
-      int& iDstLen, int& iWidth, int& iHeight, int& iColorFormat) {
-    EXPECT_TRUE(gThis == this);
-    return static_cast<DECODING_STATE>(5);
-  }
-  virtual long EXTAPI SetOption (DECODER_OPTION eOptionId, void* pOption) {
-    EXPECT_TRUE(gThis == this);
-    return 6;
-  }
-  virtual long EXTAPI GetOption (DECODER_OPTION eOptionId, void* pOption) {
-    EXPECT_TRUE(gThis == this);
-    return 7;
-  }
-};
-
-TEST(ISVCEncoderTest, CheckFunctionOrder) {
-  SVCEncoderImpl* p = new SVCEncoderImpl;
-  gThis = p;
-  CheckEncoderInterface(p, CheckFunctionOrder);
-  delete p;
-}
-
-TEST(ISVCDecoderTest, CheckFunctionOrder) {
-  SVCDecoderImpl* p = new SVCDecoderImpl;
-  gThis = p;
-  CheckDecoderInterface(p, CheckFunctionOrder);
-  delete p;
-}
-
-struct bool_test_struct {
-  char c;
-  bool b;
-};
-
-TEST(ISVCDecoderEncoderTest, CheckCAbi) {
-  EXPECT_EQ(sizeof(bool), GetBoolSize()) << "Wrong size of bool type";
-  EXPECT_EQ(offsetof(bool_test_struct, b), GetBoolOffset()) << "Wrong alignment of bool in a struct";
-  EXPECT_EQ(sizeof(bool_test_struct), GetBoolStructSize()) << "Wrong size of struct with a bool";
-}
--- a/test/decode_encode_test.cpp
+++ /dev/null
@@ -1,112 +1,0 @@
-#include <gtest/gtest.h>
-#include "codec_def.h"
-#include "utils/HashFunctions.h"
-#include "utils/BufferedData.h"
-#include "utils/InputStream.h"
-#include "BaseDecoderTest.h"
-#include "BaseEncoderTest.h"
-
-static void UpdateHashFromFrame(const SFrameBSInfo& info, SHA1Context* ctx) {
-  for (int i = 0; i < info.iLayerNum; ++i) {
-    const SLayerBSInfo& layerInfo = info.sLayerInfo[i];
-    int layerSize = 0;
-    for (int j = 0; j < layerInfo.iNalCount; ++j) {
-      layerSize += layerInfo.iNalLengthInByte[j];
-    }
-    SHA1Input(ctx, layerInfo.pBsBuf, layerSize);
-  }
-}
-
-static void WritePlaneBuffer(BufferedData* buf, const uint8_t* plane,
-    int width, int height, int stride) {
-  for (int i = 0; i < height; i++) {
-    if (!buf->PushBack(plane, width)) {
-      FAIL() << "unable to allocate memory";
-    }
-    plane += stride;
-  }
-}
-
-struct DecodeEncodeFileParam {
-  const char* fileName;
-  const char* hashStr;
-  int width;
-  int height;
-  float frameRate;
-};
-
-class DecodeEncodeTest : public ::testing::TestWithParam<DecodeEncodeFileParam>,
-    public BaseDecoderTest, public BaseDecoderTest::Callback,
-    public BaseEncoderTest , public BaseEncoderTest::Callback,
-    public InputStream {
- public:
-  virtual void SetUp() {
-    BaseDecoderTest::SetUp();
-    if (HasFatalFailure()) {
-      return;
-    }
-    BaseEncoderTest::SetUp();
-    if (HasFatalFailure()) {
-      return;
-    }
-    SHA1Reset(&ctx_);
-  }
-
-  virtual void TearDown() {
-    BaseDecoderTest::TearDown();
-    BaseEncoderTest::TearDown();
-  }
-
-  virtual void onDecodeFrame(const Frame& frame) {
-    const Plane& y = frame.y;
-    const Plane& u = frame.u;
-    const Plane& v = frame.v;
-    WritePlaneBuffer(&buf_, y.data, y.width, y.height, y.stride);
-    WritePlaneBuffer(&buf_, u.data, u.width, u.height, u.stride);
-    WritePlaneBuffer(&buf_, v.data, v.width, v.height, v.stride);
-  }
-
-  virtual void onEncodeFrame(const SFrameBSInfo& frameInfo) {
-    UpdateHashFromFrame(frameInfo, &ctx_);
-  }
-
-  virtual int read(void* ptr, size_t len) {
-    while (buf_.Length() < len) {
-      bool hasNext = DecodeNextFrame(this);
-      if (HasFatalFailure()) {
-        return -1;
-      }
-      if (!hasNext) {
-        if (buf_.Length() == 0) {
-          return -1;
-        }
-        break;
-      }
-    }
-    return buf_.PopFront(static_cast<uint8_t*>(ptr), len);
-  }
-
- protected:
-  SHA1Context ctx_;
-  BufferedData buf_;
-};
-
-TEST_P(DecodeEncodeTest, CompareOutput) {
-  DecodeEncodeFileParam p = GetParam();
-
-  ASSERT_TRUE(Open(p.fileName));
-  EncodeStream(this, p.width, p.height, p.frameRate, SM_SINGLE_SLICE, false, 1, 1, this);
-  unsigned char digest[SHA_DIGEST_LENGTH];
-  SHA1Result(&ctx_, digest);
-  if (!HasFatalFailure()) {
-    CompareHash(digest, p.hashStr);
-  }
-}
-
-static const DecodeEncodeFileParam kFileParamArray[] = {
-  {"res/test_vd_1d.264", "c04a5978eb715837c29463e79b6598a05136829f", 320, 192, 12.0f},
-  {"res/test_vd_rc.264", "40d8eb5a54d358c663f836c689a158c326de4b1c", 320, 192, 12.0f},
-};
-
-INSTANTIATE_TEST_CASE_P(DecodeEncodeFile, DecodeEncodeTest,
-    ::testing::ValuesIn(kFileParamArray));
--- /dev/null
+++ b/test/decoder/DecUT_ExpandPicture.cpp
@@ -1,0 +1,215 @@
+#include<gtest/gtest.h>
+#include "codec_def.h"
+#include "expand_pic.h"
+#include "mem_align.h"
+using namespace WelsDec;
+#define EXPAND_PIC_TEST_NUM 10
+namespace WelsDec {
+extern PPicture AllocPicture (PWelsDecoderContext pCtx, const int32_t kPicWidth, const int32_t kPicHeight);
+extern void FreePicture (PPicture pPic);
+}
+#define H264_PADDING_LENGTH_LUMA (PADDING_LENGTH)
+#define H264_PADDING_LENGTH_CHROMA (PADDING_LENGTH>>1)
+
+void H264ExpandPictureLumaAnchor_c (uint8_t* pDst, int32_t iStride, int32_t iPicWidth, int32_t iPicHeight) {
+  uint8_t* pTmp = pDst;
+  uint8_t* pDstLastLine = pTmp + (iPicHeight - 1) * iStride;
+  uint8_t pTL = pTmp[0];
+  uint8_t pTR = pTmp[iPicWidth - 1];
+  uint8_t pBL = pDstLastLine[0];
+  uint8_t pBR = pDstLastLine[iPicWidth - 1];
+  int32_t i = 0;
+
+  do {
+    const int32_t kStrides = (1 + i) * iStride;
+    uint8_t* pTop = pTmp - kStrides;
+    uint8_t* pBottom = pDstLastLine + kStrides;
+
+    // pad pTop and pBottom
+    memcpy (pTop, pTmp, iPicWidth);
+    memcpy (pBottom, pDstLastLine, iPicWidth);
+
+    // pad corners
+    memset (pTop - H264_PADDING_LENGTH_LUMA, pTL, H264_PADDING_LENGTH_LUMA); //pTop left
+    memset (pTop + iPicWidth, pTR, H264_PADDING_LENGTH_LUMA); //pTop right
+    memset (pBottom - H264_PADDING_LENGTH_LUMA, pBL, H264_PADDING_LENGTH_LUMA); //pBottom left
+    memset (pBottom + iPicWidth, pBR, H264_PADDING_LENGTH_LUMA); //pBottom right
+    ++ i;
+  } while (i < H264_PADDING_LENGTH_LUMA);
+
+  // pad left and right
+  i = 0;
+  do {
+    memset (pTmp - H264_PADDING_LENGTH_LUMA, pTmp[0], H264_PADDING_LENGTH_LUMA);
+    memset (pTmp + iPicWidth, pTmp[iPicWidth - 1], H264_PADDING_LENGTH_LUMA);
+    pTmp += iStride;
+    ++ i;
+  } while (i < iPicHeight);
+}
+
+void H264ExpandPictureChromaAnchor_c (uint8_t* pDst, int32_t iStride, int32_t iPicWidth, int32_t iPicHeight) {
+  uint8_t* pTmp = pDst;
+  uint8_t* pDstLastLine = pTmp + (iPicHeight - 1) * iStride;
+  uint8_t pTL = pTmp[0];
+  uint8_t pTR = pTmp[iPicWidth - 1];
+  uint8_t pBL = pDstLastLine[0];
+  uint8_t pBR = pDstLastLine[iPicWidth - 1];
+  int32_t i = 0;
+
+  do {
+    const int32_t kStrides = (1 + i) * iStride;
+    uint8_t* pTop = pTmp - kStrides;
+    uint8_t* pBottom = pDstLastLine + kStrides;
+
+    // pad pTop and pBottom
+    memcpy (pTop, pTmp, iPicWidth);
+    memcpy (pBottom, pDstLastLine, iPicWidth);
+
+    // pad corners
+    memset (pTop - H264_PADDING_LENGTH_CHROMA, pTL, H264_PADDING_LENGTH_CHROMA); //pTop left
+    memset (pTop + iPicWidth, pTR, H264_PADDING_LENGTH_CHROMA); //pTop right
+    memset (pBottom - H264_PADDING_LENGTH_CHROMA, pBL, H264_PADDING_LENGTH_CHROMA); //pBottom left
+    memset (pBottom + iPicWidth, pBR, H264_PADDING_LENGTH_CHROMA); //pBottom right
+
+    ++ i;
+  } while (i < H264_PADDING_LENGTH_CHROMA);
+
+  // pad left and right
+  i = 0;
+  do {
+    memset (pTmp - H264_PADDING_LENGTH_CHROMA, pTmp[0], H264_PADDING_LENGTH_CHROMA);
+    memset (pTmp + iPicWidth, pTmp[iPicWidth - 1], H264_PADDING_LENGTH_CHROMA);
+
+    pTmp += iStride;
+    ++ i;
+  } while (i < iPicHeight);
+}
+
+bool CompareBuff (uint8_t* pSrc0, uint8_t* pSrc1, int32_t iStride, int32_t iWidth, int32_t iHeight) {
+  for (int32_t j = 0; j < iHeight; j++) {
+    for (int32_t i = 0; i < iWidth; i++) {
+      if (pSrc0[i + j * iStride] !=  pSrc1[i + j * iStride]) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+TEST (ExpandPicture, ExpandPictureLuma) {
+  SExpandPicFunc	    sExpandPicFunc;
+  InitExpandPictureFunc (&sExpandPicFunc, 0);
+  srand ((unsigned int)time (0));
+  for (int32_t iTestIdx = 0; iTestIdx < EXPAND_PIC_TEST_NUM; iTestIdx++) {
+    int32_t iPicWidth = 16 + (rand() % 200) * 16;
+    int32_t iPicHeight = 16 + (rand() % 100) * 16;
+
+    int32_t iStride = iPicWidth + H264_PADDING_LENGTH_LUMA * 2;
+    int32_t iBuffHeight = iPicHeight + H264_PADDING_LENGTH_LUMA * 2;
+    int32_t iBuffSize =  iBuffHeight * iStride * sizeof (uint8_t);
+    uint8_t* pAnchorDstBuff = static_cast<uint8_t*> (WelsMalloc (iBuffSize, "pAnchorDstBuff"));
+    uint8_t* pAnchorDst = pAnchorDstBuff + H264_PADDING_LENGTH_LUMA * iStride + H264_PADDING_LENGTH_LUMA;
+
+    uint8_t* pTestDstBuff = static_cast<uint8_t*> (WelsMalloc (iBuffSize, "pTestDstBuff"));
+    uint8_t* pTestDst = pTestDstBuff + H264_PADDING_LENGTH_LUMA * iStride + H264_PADDING_LENGTH_LUMA;
+
+    // Generate Src
+    for (int32_t j = 0; j < iPicHeight; j++) {
+      for (int32_t i = 0; i < iPicWidth; i++) {
+        pAnchorDst[i + j * iStride] = pTestDst[i + j * iStride] = rand() % 256;
+      }
+    }
+    H264ExpandPictureLumaAnchor_c (pAnchorDst, iStride, iPicWidth, iPicHeight);
+    sExpandPicFunc.pExpandLumaPicture (pTestDst, iStride, iPicWidth, iPicHeight);
+    EXPECT_EQ (CompareBuff (pAnchorDstBuff, pTestDstBuff, iStride, iPicWidth + H264_PADDING_LENGTH_LUMA * 2,
+                            iPicHeight + H264_PADDING_LENGTH_LUMA * 2), true);
+
+    WELS_SAFE_FREE (pAnchorDstBuff, "pAnchorDstBuff");
+    WELS_SAFE_FREE (pTestDstBuff, "pTestDstBuff");
+  }
+
+}
+
+TEST (ExpandPicture, ExpandPictureChroma) {
+  SExpandPicFunc	    sExpandPicFunc;
+  InitExpandPictureFunc (&sExpandPicFunc, 0);
+  srand ((unsigned int)time (0));
+
+  for (int32_t iTestIdx = 0; iTestIdx < EXPAND_PIC_TEST_NUM; iTestIdx++) {
+    int32_t iPicWidth = (8 + (rand() % 200) * 8);
+    int32_t iPicHeight = (8 + (rand() % 100) * 8);
+
+    int32_t iStride = (iPicWidth + H264_PADDING_LENGTH_CHROMA * 2 + 8) >> 4 << 4;
+    int32_t iBuffHeight = iPicHeight + H264_PADDING_LENGTH_CHROMA * 2;
+    int32_t iBuffSize =  iBuffHeight * iStride * sizeof (uint8_t);
+    uint8_t* pAnchorDstBuff = static_cast<uint8_t*> (WelsMalloc (iBuffSize, "pAnchorDstBuff"));
+    uint8_t* pAnchorDst = pAnchorDstBuff + H264_PADDING_LENGTH_CHROMA * iStride + H264_PADDING_LENGTH_CHROMA;
+
+    uint8_t* pTestDstBuff = static_cast<uint8_t*> (WelsMalloc (iBuffSize, "pTestDstBuff"));
+    uint8_t* pTestDst = pTestDstBuff + H264_PADDING_LENGTH_CHROMA * iStride + H264_PADDING_LENGTH_CHROMA;
+
+    // Generate Src
+    for (int32_t j = 0; j < iPicHeight; j++) {
+      for (int32_t i = 0; i < iPicWidth; i++) {
+        pAnchorDst[i + j * iStride] =  pTestDst[i + j * iStride] = rand() % 256;
+      }
+    }
+    H264ExpandPictureChromaAnchor_c (pAnchorDst, iStride, iPicWidth, iPicHeight);
+    sExpandPicFunc.pExpandChromaPicture[0] (pTestDst, iStride, iPicWidth, iPicHeight);
+    EXPECT_EQ (CompareBuff (pAnchorDstBuff, pTestDstBuff, iStride, iPicWidth + H264_PADDING_LENGTH_CHROMA * 2,
+                            iPicHeight + H264_PADDING_LENGTH_CHROMA * 2), true);
+
+    WELS_SAFE_FREE (pAnchorDstBuff, "pAnchorDstBuff");
+    WELS_SAFE_FREE (pTestDstBuff, "pTestDstBuff");
+  }
+
+}
+
+TEST (ExpandPicture, ExpandPicForMotion) {
+  SExpandPicFunc	    sExpandPicFunc;
+  InitExpandPictureFunc (&sExpandPicFunc, 0);
+  srand ((unsigned int)time (0));
+  SWelsDecoderContext sCtx;
+  PPicture pPicAnchor = NULL;
+  PPicture pPicTest = NULL;
+  for (int32_t iTestIdx = 0; iTestIdx < EXPAND_PIC_TEST_NUM; iTestIdx++) {
+    int32_t iPicWidth = (16 + (rand() % 200) * 16);
+    int32_t iPicHeight = (16 + (rand() % 100) * 16);
+
+    pPicAnchor = AllocPicture (&sCtx, iPicWidth, iPicHeight);
+    pPicTest = AllocPicture (&sCtx, iPicWidth, iPicHeight);
+    sCtx.pDec = pPicTest;
+
+    int32_t iStride = pPicAnchor->iLinesize[0];
+    int32_t iStrideC;
+    iStrideC = pPicAnchor->iLinesize[1];
+    // Generate Src
+    for (int32_t j = 0; j < iPicHeight; j++) {
+      for (int32_t i = 0; i < iPicWidth; i++) {
+        pPicAnchor->pData[0][i + j * iStride] =  pPicTest->pData[0][i + j * iStride] = rand() % 256;
+      }
+    }
+    for (int32_t j = 0; j < iPicHeight / 2; j++) {
+      for (int32_t i = 0; i < iPicWidth / 2; i++) {
+        pPicAnchor->pData[1][i + j * iStrideC] =  pPicTest->pData[1][i + j * iStrideC] = rand() % 256;
+        pPicAnchor->pData[2][i + j * iStrideC] =  pPicTest->pData[2][i + j * iStrideC] = rand() % 256;
+      }
+    }
+
+    H264ExpandPictureLumaAnchor_c (pPicAnchor->pData[0], iStride, iPicWidth, iPicHeight);
+    H264ExpandPictureChromaAnchor_c (pPicAnchor->pData[1], iStrideC, iPicWidth / 2, iPicHeight / 2);
+    H264ExpandPictureChromaAnchor_c (pPicAnchor->pData[2], iStrideC, iPicWidth / 2, iPicHeight / 2);
+    ExpandReferencingPicture (sCtx.pDec, sExpandPicFunc.pExpandLumaPicture, sExpandPicFunc.pExpandChromaPicture);
+
+    EXPECT_EQ (CompareBuff (pPicAnchor->pBuffer[0], pPicTest->pBuffer[0], iStride, iPicWidth + PADDING_LENGTH * 2,
+                            iPicHeight + PADDING_LENGTH * 2), true);
+    EXPECT_EQ (CompareBuff (pPicAnchor->pBuffer[1], pPicTest->pBuffer[1], iStrideC, iPicWidth / 2 + PADDING_LENGTH,
+                            iPicHeight / 2 + PADDING_LENGTH), true);
+    EXPECT_EQ (CompareBuff (pPicAnchor->pBuffer[2], pPicTest->pBuffer[2], iStrideC, iPicWidth / 2 + PADDING_LENGTH,
+                            iPicHeight / 2 + PADDING_LENGTH), true);
+
+    FreePicture (pPicAnchor);
+    FreePicture (pPicTest);
+  }
+}
+
--- /dev/null
+++ b/test/decoder/DecUT_IdctResAddPred.cpp
@@ -1,0 +1,83 @@
+#include <gtest/gtest.h>
+#include <time.h>
+#include "macros.h"
+#include "decode_mb_aux.h"
+using namespace WelsDec;
+void IdctResAddPred_ref (uint8_t* pPred, const int32_t kiStride, int16_t* pRs) {
+  int16_t iSrc[16];
+
+  uint8_t* pDst			= pPred;
+  const int32_t kiStride2	= kiStride << 1;
+  const int32_t kiStride3	= kiStride + kiStride2;
+  int32_t i;
+
+  for (i = 0; i < 4; i++) {
+    const int32_t kiY  = i << 2;
+    const int32_t kiT0 = pRs[kiY] + pRs[kiY + 2];
+    const int32_t kiT1 = pRs[kiY] - pRs[kiY + 2];
+    const int32_t kiT2 = (pRs[kiY + 1] >> 1) - pRs[kiY + 3];
+    const int32_t kiT3 = pRs[kiY + 1] + (pRs[kiY + 3] >> 1);
+
+    iSrc[kiY] = kiT0 + kiT3;
+    iSrc[kiY + 1] = kiT1 + kiT2;
+    iSrc[kiY + 2] = kiT1 - kiT2;
+    iSrc[kiY + 3] = kiT0 - kiT3;
+  }
+
+  for (i = 0; i < 4; i++) {
+    int32_t kT1	= iSrc[i]	+ iSrc[i + 8];
+    int32_t kT2	= iSrc[i + 4] + (iSrc[i + 12] >> 1);
+    int32_t kT3	= (32 + kT1 + kT2) >> 6;
+    int32_t kT4	= (32 + kT1 - kT2) >> 6;
+
+    pDst[i] = WelsClip1 (kT3 + pPred[i]);
+    pDst[i + kiStride3] = WelsClip1 (kT4 + pPred[i + kiStride3]);
+
+    kT1	= iSrc[i] - iSrc[i + 8];
+    kT2	= (iSrc[i + 4] >> 1) - iSrc[i + 12];
+    pDst[i + kiStride] = WelsClip1 (((32 + kT1 + kT2) >> 6) + pDst[i + kiStride]);
+    pDst[i + kiStride2] = WelsClip1 (((32 + kT1 - kT2) >> 6) + pDst[i + kiStride2]);
+  }
+}
+
+#define GENERATE_IDCTRESADDPRED(pred) \
+TEST(DecoderDecodeMbAux, pred) {\
+  const int32_t kiStride = 32;\
+  const int iBits = 12;\
+  const int iMask = (1 << iBits) - 1;\
+  const int iOffset = 1 << (iBits - 1);\
+  int16_t iRS[16];\
+  uint8_t uiPred[16*kiStride];\
+  int16_t iRefRS[16];\
+  uint8_t uiRefPred[16*kiStride];\
+  int32_t iRunTimes = 1000;\
+  srand((unsigned int)time(NULL));\
+  while(iRunTimes--) {\
+    for(int i = 0; i < 4; i++)\
+      for(int j = 0; j < 4; j++)\
+        iRefRS[i*4+j] = iRS[i*4+j] = (rand() & iMask) - iOffset;\
+    for(int i = 0; i < 4; i++)\
+      for(int j = 0; j < 4; j++)\
+        uiRefPred[i * kiStride + j] = uiPred[i * kiStride + j] = rand() & 255;\
+    pred(uiPred, kiStride, iRS);\
+    IdctResAddPred_ref(uiRefPred, kiStride, iRefRS);\
+    bool ok = true;\
+    for(int i = 0; i < 4; i++)\
+      for(int j = 0; j < 4; j++)\
+        if (uiRefPred[i * kiStride + j] != uiPred[i * kiStride + j]) {\
+          ok = false;\
+          goto next;\
+        }\
+    next:\
+    EXPECT_EQ(ok, true);\
+  }\
+}
+
+GENERATE_IDCTRESADDPRED (IdctResAddPred_c)
+#if defined(X86_ASM)
+GENERATE_IDCTRESADDPRED (IdctResAddPred_mmx)
+#endif
+
+#if defined(HAVE_NEON)
+GENERATE_IDCTRESADDPRED (IdctResAddPred_neon)
+#endif
--- /dev/null
+++ b/test/decoder/DecUT_IntraPrediction.cpp
@@ -1,0 +1,611 @@
+#include<gtest/gtest.h>
+#include <time.h>
+#include "get_intra_predictor.h"
+#include "typedefs.h"
+#include "ls_defines.h"
+using namespace WelsDec;
+#define GENERATE_4x4_UT(pred, ref) \
+  TEST(DecoderIntraPredictionTest, pred) { \
+  const int32_t kiStride = 32; \
+  int32_t iRunTimes = 1000; \
+  uint8_t pPredBuffer[9 * kiStride]; \
+  uint8_t pRefBuffer[9 * kiStride]; \
+  srand((unsigned int)time(NULL)); \
+  while(iRunTimes--) {\
+  for (int i = 0; i < 9; i++) {\
+    pRefBuffer[i] = pPredBuffer[i] = rand() & 255; \
+    pRefBuffer[i * kiStride] = pPredBuffer[i * kiStride] = rand() & 255; \
+  } \
+  pred (&pPredBuffer[kiStride + 1], kiStride); \
+  ref (&pRefBuffer[kiStride + 1], kiStride); \
+  bool ok = true; \
+  for (int i = 0; i < 4; i++) \
+    for (int j = 0; j < 4; j++) \
+      if (pPredBuffer[(i+1) * kiStride + j + 1] != pRefBuffer[(i+1) * kiStride + j + 1]) { \
+        ok = false; \
+        break; \
+      } \
+  EXPECT_EQ(ok, true);\
+  } \
+  }
+
+#define PREDV(size) \
+void LumaI##size##x##size##PredV(uint8_t *pPred, const int32_t kiStride) {\
+  int i; \
+  for (i = 0; i < size; i++) {\
+    memcpy(pPred + i * kiStride, pPred - kiStride, size * sizeof(uint8_t)); \
+  } \
+}
+
+#define PREDH(size) \
+void LumaI##size##x##size##PredH(uint8_t *pPred, const int32_t kiStride) {\
+  for (int i = 0; i < size; i++) { \
+    memset(pPred + i * kiStride, pPred[i * kiStride - 1], size * sizeof(uint8_t));\
+  }\
+}
+
+#define PREDDC(size, log) \
+void LumaI##size##x##size##PredDC(uint8_t *pPred, const int32_t kiStride) {\
+  int iSum = size; \
+  for (int i = 0; i < size; i ++) \
+    iSum += pPred[-1 + i * kiStride] + pPred[i - kiStride]; \
+  uint8_t uiMean = iSum >>(log+1);\
+  for (int i = 0; i < size; i ++) \
+    memset(pPred + i * kiStride, uiMean, size * sizeof(uint8_t)); \
+}
+
+#define PREDDCLeft(size, log) \
+void LumaI##size##x##size##PredDCLeft(uint8_t *pPred, const int32_t kiStride) {\
+  int iSum = size/2; \
+  for (int i = 0; i < size; i ++) \
+    iSum += pPred[-1 + i * kiStride]; \
+  uint8_t uiMean = iSum >>(log);\
+  for (int i = 0; i < size; i ++) \
+    memset(pPred + i * kiStride, uiMean, size * sizeof(uint8_t)); \
+}
+
+#define PREDDCTop(size, log) \
+void LumaI##size##x##size##PredDCTop(uint8_t *pPred, const int32_t kiStride) {\
+  int iSum = size/2; \
+  for (int i = 0; i < size; i ++) \
+    iSum += pPred[i - kiStride]; \
+  uint8_t uiMean = iSum >>(log);\
+  for (int i = 0; i < size; i ++) \
+    memset(pPred + i * kiStride, uiMean, size * sizeof(uint8_t)); \
+}
+
+#define PREDDCNone(size, log) \
+void LumaI##size##x##size##PredDCNone(uint8_t *pPred, const int32_t kiStride) {\
+  uint8_t uiMean = 128;\
+  for (int i = 0; i < size; i ++) \
+    memset(pPred + i * kiStride, uiMean, size * sizeof(uint8_t)); \
+}
+
+
+/*down pLeft*/
+void WelsI4x4LumaPredDDL_ref (uint8_t* pPred, const int32_t kiStride) {
+  const int32_t kiStride2	= kiStride << 1;
+  const int32_t kiStride3	= kiStride + kiStride2;
+  /*get pTop*/
+  uint8_t* ptop			= &pPred[-kiStride];
+  const uint8_t kuiT0		= *ptop;
+  const uint8_t kuiT1		= * (ptop + 1);
+  const uint8_t kuiT2		= * (ptop + 2);
+  const uint8_t kuiT3		= * (ptop + 3);
+  const uint8_t kuiT4		= * (ptop + 4);
+  const uint8_t kuiT5		= * (ptop + 5);
+  const uint8_t kuiT6		= * (ptop + 6);
+  const uint8_t kuiT7		= * (ptop + 7);
+  const uint8_t kuiDDL0	= (2 + kuiT0 + kuiT2 + (kuiT1 << 1)) >> 2;	// kDDL0
+  const uint8_t kuiDDL1	= (2 + kuiT1 + kuiT3 + (kuiT2 << 1)) >> 2;	// kDDL1
+  const uint8_t kuiDDL2	= (2 + kuiT2 + kuiT4 + (kuiT3 << 1)) >> 2;	// kDDL2
+  const uint8_t kuiDDL3	= (2 + kuiT3 + kuiT5 + (kuiT4 << 1)) >> 2;	// kDDL3
+  const uint8_t kuiDDL4	= (2 + kuiT4 + kuiT6 + (kuiT5 << 1)) >> 2;	// kDDL4
+  const uint8_t kuiDDL5	= (2 + kuiT5 + kuiT7 + (kuiT6 << 1)) >> 2;	// kDDL5
+  const uint8_t kuiDDL6	= (2 + kuiT6 + kuiT7 + (kuiT7 << 1)) >> 2;	// kDDL6
+  const uint8_t kuiList[8] = { kuiDDL0, kuiDDL1, kuiDDL2, kuiDDL3, kuiDDL4, kuiDDL5, kuiDDL6, 0 };
+
+  ST32 (pPred          , LD32 (kuiList));
+  ST32 (pPred + kiStride , LD32 (kuiList + 1));
+  ST32 (pPred + kiStride2, LD32 (kuiList + 2));
+  ST32 (pPred + kiStride3, LD32 (kuiList + 3));
+}
+
+/*down pLeft*/
+void WelsI4x4LumaPredDDLTop_ref (uint8_t* pPred, const int32_t kiStride) {
+  const int32_t kiStride2	= kiStride << 1;
+  const int32_t kiStride3	= kiStride + kiStride2;
+  /*get pTop*/
+  uint8_t* ptop			= &pPred[-kiStride];
+  const uint8_t kuiT0		= *ptop;
+  const uint8_t kuiT1		= * (ptop + 1);
+  const uint8_t kuiT2		= * (ptop + 2);
+  const uint8_t kuiT3		= * (ptop + 3);
+  const uint16_t kuiT01	= 1 + kuiT0 + kuiT1;
+  const uint16_t kuiT12	= 1 + kuiT1 + kuiT2;
+  const uint16_t kuiT23	= 1 + kuiT2 + kuiT3;
+  const uint16_t kuiT33	= 1 + (kuiT3 << 1);
+  const uint8_t kuiDLT0	= (kuiT01 + kuiT12) >> 2;	// kDLT0
+  const uint8_t kuiDLT1	= (kuiT12 + kuiT23) >> 2;	// kDLT1
+  const uint8_t kuiDLT2	= (kuiT23 + kuiT33) >> 2;	// kDLT2
+  const uint8_t kuiDLT3	= kuiT33 >> 1;			// kDLT3
+  const uint8_t kuiList[8] = { kuiDLT0, kuiDLT1, kuiDLT2, kuiDLT3, kuiDLT3, kuiDLT3, kuiDLT3 , kuiDLT3 };
+
+  ST32 (pPred,           LD32 (kuiList));
+  ST32 (pPred + kiStride,  LD32 (kuiList + 1));
+  ST32 (pPred + kiStride2, LD32 (kuiList + 2));
+  ST32 (pPred + kiStride3, LD32 (kuiList + 3));
+}
+
+
+/*down right*/
+void WelsI4x4LumaPredDDR_ref (uint8_t* pPred, const int32_t kiStride) {
+  const int32_t kiStride2	= kiStride << 1;
+  const int32_t kiStride3	= kiStride + kiStride2;
+  uint8_t* ptopleft		= &pPred[- (kiStride + 1)];
+  uint8_t* pleft			= &pPred[-1];
+  const uint8_t kuiLT		= *ptopleft;
+  /*get pLeft and pTop*/
+  const uint8_t kuiL0		= *pleft;
+  const uint8_t kuiL1		= * (pleft + kiStride);
+  const uint8_t kuiL2		= * (pleft + kiStride2);
+  const uint8_t kuiL3		= * (pleft + kiStride3);
+  const uint8_t kuiT0		= * (ptopleft + 1);
+  const uint8_t kuiT1		= * (ptopleft + 2);
+  const uint8_t kuiT2		= * (ptopleft + 3);
+  const uint8_t kuiT3		= * (ptopleft + 4);
+  const uint16_t kuiTL0	= 1 + kuiLT + kuiL0;
+  const uint16_t kuiLT0	= 1 + kuiLT + kuiT0;
+  const uint16_t kuiT01	= 1 + kuiT0 + kuiT1;
+  const uint16_t kuiT12	= 1 + kuiT1 + kuiT2;
+  const uint16_t kuiT23	= 1 + kuiT2 + kuiT3;
+  const uint16_t kuiL01	= 1 + kuiL0 + kuiL1;
+  const uint16_t kuiL12	= 1 + kuiL1 + kuiL2;
+  const uint16_t kuiL23	= 1 + kuiL2 + kuiL3;
+  const uint8_t kuiDDR0	= (kuiTL0 + kuiLT0) >> 2;	// kuiDDR0
+  const uint8_t kuiDDR1	= (kuiLT0 + kuiT01) >> 2;	// kuiDDR1
+  const uint8_t kuiDDR2	= (kuiT01 + kuiT12) >> 2;	// kuiDDR2
+  const uint8_t kuiDDR3	= (kuiT12 + kuiT23) >> 2;	// kuiDDR3
+  const uint8_t kuiDDR4	= (kuiTL0 + kuiL01) >> 2;	// kuiDDR4
+  const uint8_t kuiDDR5	= (kuiL01 + kuiL12) >> 2;	// kuiDDR5
+  const uint8_t kuiDDR6	= (kuiL12 + kuiL23) >> 2;	// kuiDDR6
+  const uint8_t kuiList[8] = { kuiDDR6, kuiDDR5, kuiDDR4, kuiDDR0, kuiDDR1, kuiDDR2, kuiDDR3, 0	};
+
+  ST32 (pPred          , LD32 (kuiList + 3));
+  ST32 (pPred + kiStride , LD32 (kuiList + 2));
+  ST32 (pPred + kiStride2, LD32 (kuiList + 1));
+  ST32 (pPred + kiStride3, LD32 (kuiList));
+}
+
+
+/*vertical pLeft*/
+void WelsI4x4LumaPredVL_ref (uint8_t* pPred, const int32_t kiStride) {
+  const int32_t kiStride2	= kiStride << 1;
+  const int32_t kiStride3	= kiStride + kiStride2;
+  uint8_t* ptopleft		= &pPred[- (kiStride + 1)];
+  /*get pTop*/
+  const uint8_t kuiT0		    = * (ptopleft + 1);
+  const uint8_t kuiT1		    = * (ptopleft + 2);
+  const uint8_t kuiT2		    = * (ptopleft + 3);
+  const uint8_t kuiT3		    = * (ptopleft + 4);
+  const uint8_t kuiT4		    = * (ptopleft + 5);
+  const uint8_t kuiT5		    = * (ptopleft + 6);
+  const uint8_t kuiT6		    = * (ptopleft + 7);
+  const uint16_t kuiT01		= 1 + kuiT0 + kuiT1;
+  const uint16_t kuiT12		= 1 + kuiT1 + kuiT2;
+  const uint16_t kuiT23		= 1 + kuiT2 + kuiT3;
+  const uint16_t kuiT34		= 1 + kuiT3 + kuiT4;
+  const uint16_t kuiT45		= 1 + kuiT4 + kuiT5;
+  const uint16_t kuiT56		= 1 + kuiT5 + kuiT6;
+  const uint8_t kuiVL0		= kuiT01 >> 1;			// kuiVL0
+  const uint8_t kuiVL1		= kuiT12 >> 1;			// kuiVL1
+  const uint8_t kuiVL2		= kuiT23 >> 1;			// kuiVL2
+  const uint8_t kuiVL3		= kuiT34 >> 1;			// kuiVL3
+  const uint8_t kuiVL4		= kuiT45 >> 1;			// kuiVL4
+  const uint8_t kuiVL5		= (kuiT01 + kuiT12) >> 2;	// kuiVL5
+  const uint8_t kuiVL6		= (kuiT12 + kuiT23) >> 2;	// kuiVL6
+  const uint8_t kuiVL7		= (kuiT23 + kuiT34) >> 2;	// kuiVL7
+  const uint8_t kuiVL8		= (kuiT34 + kuiT45) >> 2;	// kuiVL8
+  const uint8_t kuiVL9		= (kuiT45 + kuiT56) >> 2;	// kuiVL9
+  const uint8_t kuiList[10]	= { kuiVL0, kuiVL1, kuiVL2, kuiVL3, kuiVL4, kuiVL5, kuiVL6, kuiVL7, kuiVL8, kuiVL9 };
+
+  ST32 (pPred,           LD32 (kuiList));
+  ST32 (pPred + kiStride,  LD32 (kuiList + 5));
+  ST32 (pPred + kiStride2, LD32 (kuiList + 1));
+  ST32 (pPred + kiStride3, LD32 (kuiList + 6));
+}
+
+/*vertical pLeft*/
+void WelsI4x4LumaPredVLTop_ref (uint8_t* pPred, const int32_t kiStride) {
+  const int32_t kiStride2	    = kiStride << 1;
+  const int32_t kiStride3	    = kiStride + kiStride2;
+  uint8_t* ptopleft		    = &pPred[- (kiStride + 1)];
+  /*get pTop*/
+  const uint8_t kuiT0		    = * (ptopleft + 1);
+  const uint8_t kuiT1		    = * (ptopleft + 2);
+  const uint8_t kuiT2		    = * (ptopleft + 3);
+  const uint8_t kuiT3		    = * (ptopleft + 4);
+  const uint16_t kuiT01		= 1 + kuiT0 + kuiT1;
+  const uint16_t kuiT12		= 1 + kuiT1 + kuiT2;
+  const uint16_t kuiT23		= 1 + kuiT2 + kuiT3;
+  const uint16_t kuiT33		= 1 + (kuiT3 << 1);
+  const uint8_t kuiVL0		= kuiT01 >> 1;
+  const uint8_t kuiVL1		= kuiT12 >> 1;
+  const uint8_t kuiVL2		= kuiT23 >> 1;
+  const uint8_t kuiVL3		= kuiT33 >> 1;
+  const uint8_t kuiVL4		= (kuiT01 + kuiT12) >> 2;
+  const uint8_t kuiVL5		= (kuiT12 + kuiT23) >> 2;
+  const uint8_t kuiVL6		= (kuiT23 + kuiT33) >> 2;
+  const uint8_t kuiVL7		= kuiVL3;
+  const uint8_t kuiList[10]	= { kuiVL0, kuiVL1, kuiVL2, kuiVL3, kuiVL3, kuiVL4, kuiVL5, kuiVL6, kuiVL7, kuiVL7 };
+
+  ST32 (pPred          , LD32 (kuiList));
+  ST32 (pPred + kiStride , LD32 (kuiList + 5));
+  ST32 (pPred + kiStride2, LD32 (kuiList + 1));
+  ST32 (pPred + kiStride3, LD32 (kuiList + 6));
+}
+
+
+/*vertical right*/
+void WelsI4x4LumaPredVR_ref (uint8_t* pPred, const int32_t kiStride) {
+  const int32_t kiStride2	    = kiStride << 1;
+  const int32_t kiStride3	    = kiStride + kiStride2;
+  const uint8_t kuiLT		    = pPred[-kiStride - 1];
+  /*get pLeft and pTop*/
+  const uint8_t kuiL0		    = pPred[         -1];
+  const uint8_t kuiL1		    = pPred[kiStride - 1];
+  const uint8_t kuiL2		    = pPred[kiStride2 - 1];
+  const uint8_t kuiT0		    = pPred[ -kiStride];
+  const uint8_t kuiT1		    = pPred[1 - kiStride];
+  const uint8_t kuiT2		    = pPred[2 - kiStride];
+  const uint8_t kuiT3		    = pPred[3 - kiStride];
+  const uint8_t kuiVR0		= (1 + kuiLT + kuiT0) >> 1;	// kuiVR0
+  const uint8_t kuiVR1		= (1 + kuiT0 + kuiT1) >> 1;	// kuiVR1
+  const uint8_t kuiVR2		= (1 + kuiT1 + kuiT2) >> 1;	// kuiVR2
+  const uint8_t kuiVR3		= (1 + kuiT2 + kuiT3) >> 1;	// kuiVR3
+  const uint8_t kuiVR4		= (2 + kuiL0 + (kuiLT << 1) + kuiT0) >> 2;	// kuiVR4
+  const uint8_t kuiVR5		= (2 + kuiLT + (kuiT0 << 1) + kuiT1) >> 2;	// kuiVR5
+  const uint8_t kuiVR6		= (2 + kuiT0 + (kuiT1 << 1) + kuiT2) >> 2;	// kuiVR6
+  const uint8_t kuiVR7		= (2 + kuiT1 + (kuiT2 << 1) + kuiT3) >> 2;	// kuiVR7
+  const uint8_t kuiVR8		= (2 + kuiLT + (kuiL0 << 1) + kuiL1) >> 2;	// kuiVR8
+  const uint8_t kuiVR9		= (2 + kuiL0 + (kuiL1 << 1) + kuiL2) >> 2;	// kuiVR9
+  const uint8_t kuiList[10]	= { kuiVR8, kuiVR0, kuiVR1, kuiVR2, kuiVR3, kuiVR9, kuiVR4, kuiVR5, kuiVR6, kuiVR7 };
+
+  ST32 (pPred          , LD32 (kuiList + 1));
+  ST32 (pPred + kiStride , LD32 (kuiList + 6));
+  ST32 (pPred + kiStride2, LD32 (kuiList));
+  ST32 (pPred + kiStride3, LD32 (kuiList + 5));
+}
+
+/*horizontal up*/
+void WelsI4x4LumaPredHU_ref (uint8_t* pPred, const int32_t kiStride) {
+  const int32_t kiStride2	    = kiStride << 1;
+  const int32_t kiStride3	    = kiStride + kiStride2;
+  /*get pLeft*/
+  const uint8_t kuiL0		    = pPred[         -1];
+  const uint8_t kuiL1		    = pPred[kiStride - 1];
+  const uint8_t kuiL2		    = pPred[kiStride2 - 1];
+  const uint8_t kuiL3		    = pPred[kiStride3 - 1];
+  const uint16_t kuiL01		= 1 + kuiL0 + kuiL1;
+  const uint16_t kuiL12		= 1 + kuiL1 + kuiL2;
+  const uint16_t kuiL23		= 1 + kuiL2 + kuiL3;
+  const uint8_t kuiHU0		= kuiL01 >> 1;
+  const uint8_t kuiHU1		= (kuiL01 + kuiL12) >> 2;
+  const uint8_t kuiHU2		= kuiL12 >> 1;
+  const uint8_t kuiHU3		= (kuiL12 + kuiL23) >> 2;
+  const uint8_t kuiHU4		= kuiL23 >> 1;
+  const uint8_t kuiHU5		= (1 + kuiL23 + (kuiL3 << 1)) >> 2;
+  const uint8_t kuiList[10]	= { kuiHU0, kuiHU1, kuiHU2, kuiHU3, kuiHU4, kuiHU5, kuiL3, kuiL3, kuiL3, kuiL3 };
+
+  ST32 (pPred          , LD32 (kuiList));
+  ST32 (pPred + kiStride , LD32 (kuiList + 2));
+  ST32 (pPred + kiStride2, LD32 (kuiList + 4));
+  ST32 (pPred + kiStride3, LD32 (kuiList + 6));
+}
+
+/*horizontal down*/
+void WelsI4x4LumaPredHD_ref (uint8_t* pPred, const int32_t kiStride) {
+  const int32_t kiStride2 	= kiStride << 1;
+  const int32_t kiStride3	    = kiStride + kiStride2;
+  const uint8_t kuiLT		    = pPred[- (kiStride + 1)];
+  /*get pLeft and pTop*/
+  const uint8_t kuiL0		    = pPred[-1          ];
+  const uint8_t kuiL1		    = pPred[-1 + kiStride ];
+  const uint8_t kuiL2		    = pPred[-1 + kiStride2];
+  const uint8_t kuiL3		    = pPred[-1 + kiStride3];
+  const uint8_t kuiT0		    = pPred[-kiStride   ];
+  const uint8_t kuiT1		    = pPred[-kiStride + 1 ];
+  const uint8_t kuiT2		    = pPred[-kiStride + 2 ];
+  const uint16_t kuiTL0		= 1 + kuiLT + kuiL0;
+  const uint16_t kuiLT0		= 1 + kuiLT + kuiT0;
+  const uint16_t kuiT01		= 1 + kuiT0 + kuiT1;
+  const uint16_t kuiT12		= 1 + kuiT1 + kuiT2;
+  const uint16_t kuiL01		= 1 + kuiL0 + kuiL1;
+  const uint16_t kuiL12		= 1 + kuiL1 + kuiL2;
+  const uint16_t kuiL23		= 1 + kuiL2 + kuiL3;
+  const uint8_t kuiHD0		= kuiTL0 >> 1;
+  const uint8_t kuiHD1		= (kuiTL0 + kuiLT0) >> 2;
+  const uint8_t kuiHD2		= (kuiLT0 + kuiT01) >> 2;
+  const uint8_t kuiHD3		= (kuiT01 + kuiT12) >> 2;
+  const uint8_t kuiHD4		= kuiL01 >> 1;
+  const uint8_t kuiHD5		= (kuiTL0 + kuiL01) >> 2;
+  const uint8_t kuiHD6		= kuiL12 >> 1;
+  const uint8_t kuiHD7		= (kuiL01 + kuiL12) >> 2;
+  const uint8_t kuiHD8		= kuiL23 >> 1;
+  const uint8_t kuiHD9	    = (kuiL12 + kuiL23) >> 2;
+  const uint8_t kuiList[10]	= { kuiHD8, kuiHD9, kuiHD6, kuiHD7, kuiHD4, kuiHD5, kuiHD0, kuiHD1, kuiHD2, kuiHD3 };
+
+  ST32 (pPred          , LD32 (kuiList + 6));
+  ST32 (pPred + kiStride , LD32 (kuiList + 4));
+  ST32 (pPred + kiStride2, LD32 (kuiList + 2));
+  ST32 (pPred + kiStride3, LD32 (kuiList));
+}
+// Unit test for Luma 4x4 cases
+PREDV (4)
+GENERATE_4x4_UT (WelsI4x4LumaPredV_c, LumaI4x4PredV)
+
+PREDH (4)
+GENERATE_4x4_UT (WelsI4x4LumaPredH_c, LumaI4x4PredH)
+
+PREDDC (4, 2)
+GENERATE_4x4_UT (WelsI4x4LumaPredDc_c, LumaI4x4PredDC)
+
+PREDDCLeft (4, 2)
+GENERATE_4x4_UT (WelsI4x4LumaPredDcLeft_c, LumaI4x4PredDCLeft)
+
+PREDDCTop (4, 2)
+GENERATE_4x4_UT (WelsI4x4LumaPredDcTop_c, LumaI4x4PredDCTop)
+
+PREDDCNone (4, 2)
+GENERATE_4x4_UT (WelsI4x4LumaPredDcNA_c, LumaI4x4PredDCNone)
+GENERATE_4x4_UT (WelsI4x4LumaPredDDL_c, WelsI4x4LumaPredDDL_ref)
+GENERATE_4x4_UT (WelsI4x4LumaPredDDLTop_c, WelsI4x4LumaPredDDLTop_ref)
+GENERATE_4x4_UT (WelsI4x4LumaPredDDR_c, WelsI4x4LumaPredDDR_ref)
+GENERATE_4x4_UT (WelsI4x4LumaPredVR_c, WelsI4x4LumaPredVR_ref)
+GENERATE_4x4_UT (WelsI4x4LumaPredVL_c, WelsI4x4LumaPredVL_ref)
+GENERATE_4x4_UT (WelsI4x4LumaPredVLTop_c, WelsI4x4LumaPredVLTop_ref)
+GENERATE_4x4_UT (WelsI4x4LumaPredHU_c, WelsI4x4LumaPredHU_ref)
+GENERATE_4x4_UT (WelsI4x4LumaPredHD_c, WelsI4x4LumaPredHD_ref)
+
+#define GENERATE_8x8_UT(pred, ref) \
+TEST(DecoderIntraPredictionTest, pred) {\
+const int32_t kiStride = 32; \
+int iRunTimes = 1000; \
+uint8_t _pRefBuffer[18 * kiStride + 64]; \
+uint8_t _pPredBuffer[18 * kiStride + 64]; \
+uint8_t *pRefBuffer, *pPredBuffer; \
+pRefBuffer = (uint8_t*)((((intptr_t)(&_pRefBuffer[31])) >> 4) << 4); \
+pPredBuffer = (uint8_t*)((((intptr_t)(&_pPredBuffer[31])) >> 4) << 4); \
+srand((unsigned int)time(NULL)); \
+while(iRunTimes--) {\
+for (int i = 0; i < 17; i ++) {\
+  pRefBuffer[i] = pPredBuffer[i] = rand() & 255; \
+  pRefBuffer[i * kiStride - 1] = pPredBuffer[i * kiStride - 1] = rand() & 255; \
+}\
+pred(&pPredBuffer[kiStride], kiStride); \
+ref(&pRefBuffer[kiStride], kiStride); \
+bool ok = true; \
+for (int i = 0; i < 8; i ++)\
+  for(int j = 0; j < 8; j ++)\
+    if (pPredBuffer[(i+1) * kiStride + j] != pRefBuffer[(i+1) * kiStride + j]) {\
+      ok = false; \
+      break; \
+    } \
+    EXPECT_EQ(ok, true); \
+} \
+}
+
+void WelsIChromaPredPlane_ref (uint8_t* pPred, const int32_t kiStride) {
+  int32_t a = 0, b = 0, c = 0, H = 0, V = 0;
+  int32_t i, j;
+  uint8_t* pTop = &pPred[-kiStride];
+  uint8_t* pLeft = &pPred[-1];
+
+  for (i = 0 ; i < 4 ; i ++) {
+    H += (i + 1) * (pTop[4 + i] - pTop[2 - i]);
+    V += (i + 1) * (pLeft[ (4 + i) * kiStride] - pLeft[ (2 - i) * kiStride]);
+  }
+
+  a = (pLeft[7 * kiStride] + pTop[7]) << 4;
+  b = (17 * H + 16) >> 5;
+  c = (17 * V + 16) >> 5;
+
+  for (i = 0 ; i < 8 ; i ++) {
+    for (j = 0 ; j < 8 ; j ++) {
+      int32_t iTmp = (a + b * (j - 3) + c * (i - 3) + 16) >> 5;
+      pPred[j] = (iTmp < 0) ? 0 : ((iTmp > 255) ? 255 : iTmp);
+    }
+    pPred += kiStride;
+  }
+}
+
+
+void WelsIChromaPredDc_ref (uint8_t* pPred, const int32_t kiStride) {
+  const int32_t kiL1		= kiStride - 1;
+  const int32_t kiL2		= kiL1 + kiStride;
+  const int32_t kiL3		= kiL2 + kiStride;
+  const int32_t kiL4		= kiL3 + kiStride;
+  const int32_t kiL5		= kiL4 + kiStride;
+  const int32_t kiL6		= kiL5 + kiStride;
+  const int32_t kiL7		= kiL6 + kiStride;
+  /*caculate the kMean value*/
+  const uint8_t kuiM1		= (pPred[-kiStride] + pPred[1 - kiStride] + pPred[2 - kiStride] + pPred[3 - kiStride] +
+                           pPred[-1] + pPred[kiL1] + pPred[kiL2] + pPred[kiL3] + 4) >> 3 ;
+  const uint32_t kuiSum2	= pPred[4 - kiStride] + pPred[5 - kiStride] + pPred[6 - kiStride] + pPred[7 - kiStride];
+  const uint32_t kuiSum3	= pPred[kiL4] + pPred[kiL5] + pPred[kiL6] + pPred[kiL7];
+  const uint8_t kuiM2		= (kuiSum2 + 2) >> 2;
+  const uint8_t kuiM3		= (kuiSum3 + 2) >> 2;
+  const uint8_t kuiM4		= (kuiSum2 + kuiSum3 + 4) >> 3;
+  const uint8_t kuiMUP[8]	= {kuiM1, kuiM1, kuiM1, kuiM1, kuiM2, kuiM2, kuiM2, kuiM2};
+  const uint8_t kuiMDown[8]	= {kuiM3, kuiM3, kuiM3, kuiM3, kuiM4, kuiM4, kuiM4, kuiM4};
+  const uint64_t kuiUP64		= LD64 (kuiMUP);
+  const uint64_t kuiDN64		= LD64 (kuiMDown);
+
+  ST64 (pPred       , kuiUP64);
+  ST64 (pPred + kiL1 + 1, kuiUP64);
+  ST64 (pPred + kiL2 + 1, kuiUP64);
+  ST64 (pPred + kiL3 + 1, kuiUP64);
+  ST64 (pPred + kiL4 + 1, kuiDN64);
+  ST64 (pPred + kiL5 + 1, kuiDN64);
+  ST64 (pPred + kiL6 + 1, kuiDN64);
+  ST64 (pPred + kiL7 + 1, kuiDN64);
+}
+
+void WelsIChromaPredDcLeft_ref (uint8_t* pPred, const int32_t kiStride) {
+  const int32_t kiL1	=   -1 + kiStride;
+  const int32_t kiL2	= kiL1 + kiStride;
+  const int32_t kiL3	= kiL2 + kiStride;
+  const int32_t kiL4	= kiL3 + kiStride;
+  const int32_t kiL5	= kiL4 + kiStride;
+  const int32_t kiL6	= kiL5 + kiStride;
+  const int32_t kiL7	= kiL6 + kiStride;
+  /*caculate the kMean value*/
+  const uint8_t kuiMUP   = (pPred[-1] + pPred[kiL1] + pPred[kiL2] + pPred[kiL3] + 2) >> 2 ;
+  const uint8_t kuiMDown = (pPred[kiL4] + pPred[kiL5] + pPred[kiL6] + pPred[kiL7] + 2) >> 2;
+  const uint64_t kuiUP64 = 0x0101010101010101ULL * kuiMUP;
+  const uint64_t kuiDN64 = 0x0101010101010101ULL * kuiMDown;
+
+  ST64 (pPred       , kuiUP64);
+  ST64 (pPred + kiL1 + 1, kuiUP64);
+  ST64 (pPred + kiL2 + 1, kuiUP64);
+  ST64 (pPred + kiL3 + 1, kuiUP64);
+  ST64 (pPred + kiL4 + 1, kuiDN64);
+  ST64 (pPred + kiL5 + 1, kuiDN64);
+  ST64 (pPred + kiL6 + 1, kuiDN64);
+  ST64 (pPred + kiL7 + 1, kuiDN64);
+}
+
+void WelsIChromaPredDcTop_ref (uint8_t* pPred, const int32_t kiStride) {
+  int32_t iTmp			= (kiStride << 3) - kiStride;
+  /*caculate the kMean value*/
+  const uint8_t kuiM1	    = (pPred[-kiStride] + pPred[1 - kiStride] + pPred[2 - kiStride] + pPred[3 - kiStride] + 2) >> 2;
+  const uint8_t kuiM2	    = (pPred[4 - kiStride] + pPred[5 - kiStride] + pPred[6 - kiStride] + pPred[7 - kiStride] + 2) >>
+                            2;
+  const uint8_t kuiM[8]	= {kuiM1, kuiM1, kuiM1, kuiM1, kuiM2, kuiM2, kuiM2, kuiM2};
+
+  uint8_t i = 7;
+
+  do {
+    ST64 (pPred + iTmp, LD64 (kuiM));
+
+    iTmp -= kiStride;
+  } while (i-- > 0);
+}
+PREDV (8)
+PREDH (8)
+PREDDCNone (8, 3)
+GENERATE_8x8_UT (WelsIChromaPredDcNA_c, LumaI8x8PredDCNone)
+GENERATE_8x8_UT (WelsIChromaPredPlane_c, WelsIChromaPredPlane_ref)
+GENERATE_8x8_UT (WelsIChromaPredDc_c, WelsIChromaPredDc_ref)
+GENERATE_8x8_UT (WelsIChromaPredDcTop_c, WelsIChromaPredDcTop_ref)
+GENERATE_8x8_UT (WelsIChromaPredDcLeft_c, WelsIChromaPredDcLeft_ref)
+GENERATE_8x8_UT (WelsIChromaPredH_c, LumaI8x8PredH)
+GENERATE_8x8_UT (WelsIChromaPredV_c, LumaI8x8PredV)
+#define GENERATE_16x16_UT(pred, ref) \
+TEST(DecoderIntraPredictionTest, pred) {\
+const int32_t kiStride = 32; \
+int32_t iRunTimes = 1000; \
+uint8_t _pRefBuffer[18 * kiStride + 64]; \
+uint8_t _pPredBuffer[18 * kiStride + 64]; \
+uint8_t *pRefBuffer, *pPredBuffer; \
+pRefBuffer = (uint8_t*)((((intptr_t)(&_pRefBuffer[31])) >> 4) << 4); \
+pPredBuffer = (uint8_t*)((((intptr_t)(&_pPredBuffer[31])) >> 4) << 4); \
+srand((unsigned int)time(NULL)); \
+while(iRunTimes--) {\
+for (int i = 0; i < 17; i ++) {\
+  pRefBuffer[i] = pPredBuffer[i] = rand() & 255; \
+  pRefBuffer[i * kiStride - 1] = pPredBuffer[i * kiStride - 1] = rand() & 255; \
+}\
+pred(&pPredBuffer[kiStride], kiStride); \
+ref(&pRefBuffer[kiStride], kiStride); \
+bool ok = true; \
+for (int i = 0; i < 16; i ++)\
+  for(int j = 0; j < 16; j ++)\
+    if (pPredBuffer[(i+1) * kiStride + j] != pRefBuffer[(i+1) * kiStride + j]) {\
+      ok = false; \
+      break; \
+    } \
+    EXPECT_EQ(ok, true); \
+} \
+}
+void WelsI16x16LumaPredPlane_ref (uint8_t* pPred, const int32_t kiStride) {
+  int32_t a = 0, b = 0, c = 0, H = 0, V = 0;
+  int32_t i, j;
+  uint8_t* pTop = &pPred[-kiStride];
+  uint8_t* pLeft = &pPred[-1];
+
+  for (i = 0 ; i < 8 ; i ++) {
+    H += (i + 1) * (pTop[8 + i] - pTop[6 - i]);
+    V += (i + 1) * (pLeft[ (8 + i) * kiStride] - pLeft[ (6 - i) * kiStride]);
+  }
+
+  a = (pLeft[15 * kiStride] + pTop[15]) << 4;
+  b = (5 * H + 32) >> 6;
+  c = (5 * V + 32) >> 6;
+
+  for (i = 0 ; i < 16 ; i ++) {
+    for (j = 0 ; j < 16 ; j ++) {
+      int32_t iTmp = (a + b * (j - 7) + c * (i - 7) + 16) >> 5;
+      pPred[j] = (iTmp < 0) ? 0 : ((iTmp > 255) ? 255 : iTmp);
+    }
+    pPred += kiStride;
+  }
+}
+
+PREDV (16)
+PREDH (16)
+PREDDC (16, 4)
+PREDDCTop (16, 4)
+PREDDCLeft (16, 4)
+PREDDCNone (16, 4)
+
+GENERATE_16x16_UT (WelsI16x16LumaPredDcNA_c, LumaI16x16PredDCNone)
+GENERATE_16x16_UT (WelsI16x16LumaPredPlane_c, WelsI16x16LumaPredPlane_ref)
+GENERATE_16x16_UT (WelsI16x16LumaPredDcLeft_c, LumaI16x16PredDCLeft)
+GENERATE_16x16_UT (WelsI16x16LumaPredDcTop_c, LumaI16x16PredDCTop)
+GENERATE_16x16_UT (WelsI16x16LumaPredDc_c, LumaI16x16PredDC)
+GENERATE_16x16_UT (WelsI16x16LumaPredH_c, LumaI16x16PredH)
+GENERATE_16x16_UT (WelsI16x16LumaPredV_c, LumaI16x16PredV)
+#if defined(X86_ASM)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredH_sse2, LumaI4x4PredH)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredDDR_mmx, WelsI4x4LumaPredDDR_ref)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredHD_mmx, WelsI4x4LumaPredHD_ref)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredHU_mmx, WelsI4x4LumaPredHU_ref)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredVR_mmx, WelsI4x4LumaPredVR_ref)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredDDL_mmx, WelsI4x4LumaPredDDL_ref)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredVL_mmx, WelsI4x4LumaPredVL_ref)
+GENERATE_8x8_UT (WelsDecoderIChromaPredDcTop_sse2, WelsIChromaPredDcTop_ref)
+GENERATE_8x8_UT (WelsDecoderIChromaPredDc_sse2, WelsIChromaPredDc_ref)
+GENERATE_8x8_UT (WelsDecoderIChromaPredPlane_sse2, WelsIChromaPredPlane_ref)
+GENERATE_8x8_UT (WelsDecoderIChromaPredH_mmx, LumaI8x8PredH)
+GENERATE_8x8_UT (WelsDecoderIChromaPredV_mmx, LumaI8x8PredV)
+GENERATE_8x8_UT (WelsDecoderIChromaPredDcLeft_mmx, WelsIChromaPredDcLeft_ref)
+GENERATE_8x8_UT (WelsDecoderIChromaPredDcNA_mmx, LumaI8x8PredDCNone)
+GENERATE_16x16_UT (WelsDecoderI16x16LumaPredPlane_sse2, WelsI16x16LumaPredPlane_ref)
+GENERATE_16x16_UT (WelsDecoderI16x16LumaPredH_sse2, LumaI16x16PredH)
+GENERATE_16x16_UT (WelsDecoderI16x16LumaPredV_sse2, LumaI16x16PredV)
+GENERATE_16x16_UT (WelsDecoderI16x16LumaPredDc_sse2, LumaI16x16PredDC)
+GENERATE_16x16_UT (WelsDecoderI16x16LumaPredDcTop_sse2, LumaI16x16PredDCTop)
+GENERATE_16x16_UT (WelsDecoderI16x16LumaPredDcNA_sse2, LumaI16x16PredDCNone)
+#endif
+
+#if defined(HAVE_NEON)
+GENERATE_16x16_UT (WelsDecoderI16x16LumaPredV_neon, LumaI16x16PredV)
+GENERATE_16x16_UT (WelsDecoderI16x16LumaPredH_neon, LumaI16x16PredH)
+GENERATE_16x16_UT (WelsDecoderI16x16LumaPredDc_neon, LumaI16x16PredDC)
+GENERATE_16x16_UT (WelsDecoderI16x16LumaPredPlane_neon, WelsI16x16LumaPredPlane_ref)
+
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredV_neon, LumaI4x4PredV)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredH_neon, LumaI4x4PredH)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredDDL_neon, WelsI4x4LumaPredDDL_ref)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredDDR_neon, WelsI4x4LumaPredDDR_ref)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredVL_neon, WelsI4x4LumaPredVL_ref)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredVR_neon, WelsI4x4LumaPredVR_ref)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredHU_neon, WelsI4x4LumaPredHU_ref)
+GENERATE_4x4_UT (WelsDecoderI4x4LumaPredHD_neon, WelsI4x4LumaPredHD_ref)
+
+GENERATE_8x8_UT (WelsDecoderIChromaPredV_neon, LumaI8x8PredV)
+GENERATE_8x8_UT (WelsDecoderIChromaPredH_neon, LumaI8x8PredH)
+GENERATE_8x8_UT (WelsDecoderIChromaPredDc_neon, WelsIChromaPredDc_ref)
+GENERATE_8x8_UT (WelsDecoderIChromaPredPlane_neon, WelsIChromaPredPlane_ref)
+#endif
--- /dev/null
+++ b/test/decoder/DecUT_PredMv.cpp
@@ -1,0 +1,670 @@
+#include<gtest/gtest.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "wels_common_basis.h"
+#include "mem_align.h"
+#include "mv_pred.h"
+#include "ls_defines.h"
+
+using namespace WelsDec;
+
+//Anchor functions
+#define REF_NOT_AVAIL    -2
+#define REF_NOT_IN_LIST  -1  //intra
+
+//cache element equal to 30
+const uint8_t g_kuiAnchorCache30ScanIdx[16] = { //mv or ref_index cache scan index, 4*4 block as basic unit
+  7,  8, 13, 14,
+  9, 10, 15, 16,
+  19, 20, 25, 26,
+  21, 22, 27, 28
+};
+
+typedef struct TagAnchorMvPred {
+  int16_t iMvArray[2][30][2];
+  int8_t iRefIdxArray[2][30];
+  int32_t iPartIdx;
+  int32_t iPartWidth;
+  int32_t iRef;
+  int16_t iMvp[2];
+} SAnchorMvPred;
+
+void AnchorPredMv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
+                   int32_t iPartIdx, int32_t iPartWidth, int8_t iRef, int16_t iMVP[2]) {
+  const uint8_t kuiLeftIdx     = g_kuiAnchorCache30ScanIdx[iPartIdx] - 1;
+  const uint8_t kuiTopIdx      = g_kuiAnchorCache30ScanIdx[iPartIdx] - 6;
+  const uint8_t kuiRightTopIdx = kuiTopIdx + iPartWidth;
+  const uint8_t kuiLeftTopIdx  = kuiTopIdx - 1;
+  const int8_t kiLeftRef       = iRefIndex[0][kuiLeftIdx];
+  const int8_t kiTopRef        = iRefIndex[0][kuiTopIdx];
+  const int8_t kiRightTopRef   = iRefIndex[0][kuiRightTopIdx];
+  const int8_t kiLeftTopRef    = iRefIndex[0][kuiLeftTopIdx];
+  int8_t iDiagonalRef  = kiRightTopRef;
+  int8_t iMatchRef = 0;
+
+  int16_t iAMV[2], iBMV[2], iCMV[2];
+
+  * (int32_t*)iAMV = INTD32 (iMotionVector[0][kuiLeftIdx]);
+  * (int32_t*)iBMV = INTD32 (iMotionVector[0][kuiTopIdx]);
+  * (int32_t*)iCMV = INTD32 (iMotionVector[0][kuiRightTopIdx]);
+
+  if (REF_NOT_AVAIL == iDiagonalRef) {
+    iDiagonalRef = kiLeftTopRef;
+    * (int32_t*)iCMV = INTD32 (iMotionVector[0][kuiLeftTopIdx]);
+  }
+
+  iMatchRef = (iRef == kiLeftRef) + (iRef == kiTopRef) + (iRef == iDiagonalRef);
+
+  if ((REF_NOT_AVAIL == kiTopRef) && (REF_NOT_AVAIL == iDiagonalRef) && (kiLeftRef >= REF_NOT_IN_LIST)) {
+    ST32 (iMVP, LD32 (iAMV));
+    return;
+  }
+
+  if (1 == iMatchRef) {
+    if (iRef == kiLeftRef) {
+      ST32 (iMVP, LD32 (iAMV));
+    } else if (iRef == kiTopRef) {
+      ST32 (iMVP, LD32 (iBMV));
+    } else {
+      ST32 (iMVP, LD32 (iCMV));
+    }
+  } else {
+    iMVP[0] = WelsMedian (iAMV[0], iBMV[0], iCMV[0]);
+    iMVP[1] = WelsMedian (iAMV[1], iBMV[1], iCMV[1]);
+  }
+}
+
+void AnchorPredInter8x16Mv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
+                            int32_t iPartIdx, int8_t iRef, int16_t iMVP[2]) {
+  if (0 == iPartIdx) {
+    const int8_t kiLeftRef = iRefIndex[0][6];
+    if (iRef == kiLeftRef) {
+      ST32 (iMVP, LD32 (&iMotionVector[0][6][0]));
+      return;
+    }
+  } else { // 4 == iPartIdx
+    int8_t iDiagonalRef = iRefIndex[0][5]; //top-right
+    int8_t index = 5;
+    if (REF_NOT_AVAIL == iDiagonalRef) {
+      iDiagonalRef = iRefIndex[0][2]; //top-left for 8*8 block(index 1)
+      index = 2;
+    }
+    if (iRef == iDiagonalRef) {
+      ST32 (iMVP, LD32 (&iMotionVector[0][index][0]));
+      return;
+    }
+  }
+
+  AnchorPredMv (iMotionVector, iRefIndex, iPartIdx, 2, iRef, iMVP);
+}
+
+void AnchorPredInter16x8Mv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
+                            int32_t iPartIdx, int8_t iRef, int16_t iMVP[2]) {
+  if (0 == iPartIdx) {
+    const int8_t kiTopRef = iRefIndex[0][1];
+    if (iRef == kiTopRef) {
+      ST32 (iMVP, LD32 (&iMotionVector[0][1][0]));
+      return;
+    }
+  } else { // 8 == iPartIdx
+    const int8_t kiLeftRef = iRefIndex[0][18];
+    if (iRef == kiLeftRef) {
+      ST32 (iMVP, LD32 (&iMotionVector[0][18][0]));
+      return;
+    }
+  }
+
+  AnchorPredMv (iMotionVector, iRefIndex, iPartIdx, 4, iRef, iMVP);
+}
+
+
+//Ref functions in WelsDec
+//Input structure for test
+typedef struct TagWelsMvPred {
+  int16_t iMvArray[2][30][2];
+  int8_t iRefIdxArray[2][30];
+  int32_t iPartIdx;
+  int32_t iPartWidth;
+  int32_t iRef;
+  int16_t iMvp[2];
+} SWelsMvPred;
+
+//mok input data
+void AssignMvInputData (SAnchorMvPred* pAncMvPred) {
+  int32_t i, j, k;
+  srand ((uint32_t)time (NULL));
+  //fill MV data and refIdx
+  for (i = 0; i < 2; ++i) {
+    for (j = 0; j < 30; ++j) {
+      for (k = 0; k < 2; ++k) {
+        pAncMvPred->iMvArray[i][j][k] = (rand() - RAND_MAX / 2);
+      }
+      pAncMvPred->iRefIdxArray[i][j] = (rand() % 18) - 2; //-2 ~ 15. 8x8 may have different values, but it matters nothing
+    }
+  }
+}
+
+void CopyMvInputData (SAnchorMvPred* pDstMvPred, SWelsMvPred* pSrcMvPred) {
+  int32_t i, j, k;
+  //fill MV data and refIdx
+  for (i = 0; i < 2; ++i) {
+    for (j = 0; j < 30; ++j) {
+      for (k = 0; k < 2; ++k) {
+        pDstMvPred->iMvArray[i][j][k] = pSrcMvPred->iMvArray[i][j][k];
+      }
+      pDstMvPred->iRefIdxArray[i][j] = pSrcMvPred->iRefIdxArray[i][j];
+    }
+  }
+}
+
+#define INIT_MV_DATA \
+  AssignMvInputData (&sAncMvPred); \
+  CopyMvInputData (&sAncMvPred, &sWelsMvPred);
+
+#define TEST_MV_PRED \
+  AnchorPredMv (sAncMvPred.iMvArray,  sAncMvPred.iRefIdxArray, iIndex, iBlockWidth, iRef,  sAncMvPred.iMvp); \
+  PredMv (sWelsMvPred.iMvArray, sWelsMvPred.iRefIdxArray, iIndex, iBlockWidth, iRef, sWelsMvPred.iMvp); \
+  bOK = ((sAncMvPred.iMvp[0] == sWelsMvPred.iMvp[0]) && (sAncMvPred.iMvp[1] == sWelsMvPred.iMvp[1])); \
+  EXPECT_EQ (bOK, true);
+
+
+//TEST cases followed
+
+TEST (PredMvTest, PredMv) {
+  SWelsMvPred  sWelsMvPred;
+  SAnchorMvPred sAncMvPred;
+  int32_t i, iRef, iBlockWidth, iIndex;
+  const int32_t kiRandTime = 100;
+  bool bOK = true;
+
+  //test specific input: 16x16
+  iIndex = 0;
+  iBlockWidth = 4;
+  i = 0;
+  srand ((uint32_t)time (NULL));
+  while (i++ < kiRandTime) {
+    iRef = (rand() % 18) - 2; //-2~15
+    INIT_MV_DATA;
+    TEST_MV_PRED;
+  }
+  //test specific input: 16x8
+  iBlockWidth = 4;
+  i = 0;
+  while (i++ < kiRandTime) {
+    iIndex = (rand() & 1) << 3; //0,8
+    iRef = (rand() % 18) - 2; //-2~15
+    INIT_MV_DATA;
+    TEST_MV_PRED;
+  }
+  //test specific input: 8x16
+  iBlockWidth = 2;
+  i = 0;
+  while (i++ < kiRandTime) {
+    iIndex = (rand() & 1) << 2; //0,4
+    iRef = (rand() % 18) - 2; //-2~15
+    INIT_MV_DATA;
+    TEST_MV_PRED;
+  }
+  //test specific input: 8x8
+  iBlockWidth = 2;
+  i = 0;
+  while (i++ < kiRandTime) {
+    iIndex = (rand() & 3) << 2; //0,4,8,12
+    iRef = (rand() % 18) - 2; //-2~15
+    INIT_MV_DATA;
+    TEST_MV_PRED;
+  }
+  //test specific input: 4x4
+  iBlockWidth = 1;
+  i = 0;
+  while (i++ < kiRandTime) {
+    iIndex = rand() & 0x0f; //0~15
+    iRef = (rand() % 18) - 2; //-2~15
+    INIT_MV_DATA;
+    TEST_MV_PRED;
+  }
+} //TEST PredMv
+
+
+TEST (PredMvTest, PredInter16x8Mv) {
+  SWelsMvPred  sWelsMvPred;
+  SAnchorMvPred sAncMvPred;
+  int32_t i, iRef, iIndex;
+  const int32_t kiRandTime = 100;
+  bool bOK = true;
+
+  i = 0;
+  srand ((uint32_t)time (NULL));
+  while (i++ < kiRandTime) {
+    iIndex = (rand() & 1) << 3; //0, 8
+    iRef = (rand() % 18) - 2; //-2~15
+    INIT_MV_DATA;
+    AnchorPredInter16x8Mv (sAncMvPred.iMvArray,  sAncMvPred.iRefIdxArray, iIndex, iRef,  sAncMvPred.iMvp);
+    PredInter16x8Mv (sWelsMvPred.iMvArray, sWelsMvPred.iRefIdxArray, iIndex, iRef, sWelsMvPred.iMvp);
+    bOK = ((sAncMvPred.iMvp[0] == sWelsMvPred.iMvp[0]) && (sAncMvPred.iMvp[1] == sWelsMvPred.iMvp[1]));
+    EXPECT_EQ (bOK, true);
+  }
+} //TEST PredInter16x8Mv
+
+TEST (PredMvTest, PredInter8x16Mv) {
+  SWelsMvPred  sWelsMvPred;
+  SAnchorMvPred sAncMvPred;
+  int32_t i, iRef, iIndex;
+  const int32_t kiRandTime = 100;
+  bool bOK = true;
+
+  i = 0;
+  srand ((uint32_t)time (NULL));
+  while (i++ < kiRandTime) {
+    iIndex = (rand() & 1) << 2; //0, 4
+    iRef = (rand() % 18) - 2; //-2~15
+    INIT_MV_DATA;
+    AnchorPredInter8x16Mv (sAncMvPred.iMvArray,  sAncMvPred.iRefIdxArray, iIndex, iRef,  sAncMvPred.iMvp);
+    PredInter8x16Mv (sWelsMvPred.iMvArray, sWelsMvPred.iRefIdxArray, iIndex, iRef, sWelsMvPred.iMvp);
+    bOK = ((sAncMvPred.iMvp[0] == sWelsMvPred.iMvp[0]) && (sAncMvPred.iMvp[1] == sWelsMvPred.iMvp[1]));
+    EXPECT_EQ (bOK, true);
+  }
+} //TEST PredInter16x8Mv
+
+void AnchorPredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) {
+  bool bTopAvail, bLeftTopAvail, bRightTopAvail, bLeftAvail;
+
+  int32_t iCurSliceIdc, iTopSliceIdc, iLeftTopSliceIdc, iRightTopSliceIdc, iLeftSliceIdc;
+  int32_t iLeftTopType, iRightTopType, iTopType, iLeftType;
+  int32_t iCurX, iCurY, iCurXy, iLeftXy, iTopXy, iLeftTopXy, iRightTopXy;
+
+  int8_t iLeftRef;
+  int8_t iTopRef;
+  int8_t iRightTopRef;
+  int8_t iLeftTopRef;
+  int8_t iDiagonalRef;
+  int8_t iMatchRef;
+  int16_t iMvA[2], iMvB[2], iMvC[2], iMvD[2];
+
+  iCurXy = pCurLayer->iMbXyIndex;
+  iCurX  = pCurLayer->iMbX;
+  iCurY  = pCurLayer->iMbY;
+  iCurSliceIdc = pCurLayer->pSliceIdc[iCurXy];
+
+  if (iCurX != 0) {
+    iLeftXy = iCurXy - 1;
+    iLeftSliceIdc = pCurLayer->pSliceIdc[iLeftXy];
+    bLeftAvail = (iLeftSliceIdc == iCurSliceIdc);
+  } else {
+    bLeftAvail = 0;
+    bLeftTopAvail = 0;
+  }
+
+  if (iCurY != 0) {
+    iTopXy = iCurXy - pCurLayer->iMbWidth;
+    iTopSliceIdc = pCurLayer->pSliceIdc[iTopXy];
+    bTopAvail = (iTopSliceIdc == iCurSliceIdc);
+    if (iCurX != 0) {
+      iLeftTopXy = iTopXy - 1;
+      iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];
+      bLeftTopAvail = (iLeftTopSliceIdc  == iCurSliceIdc);
+    } else {
+      bLeftTopAvail = 0;
+    }
+    if (iCurX != (pCurLayer->iMbWidth - 1)) {
+      iRightTopXy = iTopXy + 1;
+      iRightTopSliceIdc = pCurLayer->pSliceIdc[iRightTopXy];
+      bRightTopAvail = (iRightTopSliceIdc == iCurSliceIdc);
+    } else {
+      bRightTopAvail = 0;
+    }
+  } else {
+    bTopAvail = 0;
+    bLeftTopAvail = 0;
+    bRightTopAvail = 0;
+  }
+
+  iLeftType = ((iCurX != 0 && bLeftAvail) ? pCurLayer->pMbType[iLeftXy] : 0);
+  iTopType = ((iCurY != 0 && bTopAvail) ? pCurLayer->pMbType[iTopXy] : 0);
+  iLeftTopType = ((iCurX != 0 && iCurY != 0 && bLeftTopAvail)
+                  ? pCurLayer->pMbType[iLeftTopXy] : 0);
+  iRightTopType = ((iCurX != pCurLayer->iMbWidth - 1 && iCurY != 0 && bRightTopAvail)
+                   ? pCurLayer->pMbType[iRightTopXy] : 0);
+
+  /*get neb mv&iRefIdxArray*/
+  /*left*/
+  if (bLeftAvail && IS_INTER (iLeftType)) {
+    ST32 (iMvA, LD32 (pCurLayer->pMv[0][iLeftXy][3]));
+    iLeftRef = pCurLayer->pRefIndex[0][iLeftXy][3];
+  } else {
+    ST32 (iMvA, 0);
+    if (0 == bLeftAvail) { //not available
+      iLeftRef = REF_NOT_AVAIL;
+    } else { //available but is intra mb type
+      iLeftRef = REF_NOT_IN_LIST;
+    }
+  }
+  if (REF_NOT_AVAIL == iLeftRef ||
+      (0 == iLeftRef && 0 == * (int32_t*)iMvA)) {
+    ST32 (iMvp, 0);
+    return;
+  }
+
+  /*top*/
+  if (bTopAvail && IS_INTER (iTopType)) {
+    ST32 (iMvB, LD32 (pCurLayer->pMv[0][iTopXy][12]));
+    iTopRef = pCurLayer->pRefIndex[0][iTopXy][12];
+  } else {
+    ST32 (iMvB, 0);
+    if (0 == bTopAvail) { //not available
+      iTopRef = REF_NOT_AVAIL;
+    } else { //available but is intra mb type
+      iTopRef = REF_NOT_IN_LIST;
+    }
+  }
+  if (REF_NOT_AVAIL == iTopRef ||
+      (0 == iTopRef  && 0 == * (int32_t*)iMvB)) {
+    ST32 (iMvp, 0);
+    return;
+  }
+
+  /*right_top*/
+  if (bRightTopAvail && IS_INTER (iRightTopType)) {
+    ST32 (iMvC, LD32 (pCurLayer->pMv[0][iRightTopXy][12]));
+    iRightTopRef = pCurLayer->pRefIndex[0][iRightTopXy][12];
+  } else {
+    ST32 (iMvC, 0);
+    if (0 == bRightTopAvail) { //not available
+      iRightTopRef = REF_NOT_AVAIL;
+    } else { //available but is intra mb type
+      iRightTopRef = REF_NOT_IN_LIST;
+    }
+  }
+
+  /*left_top*/
+  if (bLeftTopAvail && IS_INTER (iLeftTopType)) {
+    ST32 (iMvD, LD32 (pCurLayer->pMv[0][iLeftTopXy][15]));
+    iLeftTopRef = pCurLayer->pRefIndex[0][iLeftTopXy][15];
+  } else {
+    ST32 (iMvD, 0);
+    if (0 == bLeftTopAvail) { //not available
+      iLeftTopRef = REF_NOT_AVAIL;
+    } else { //available but is intra mb type
+      iLeftTopRef = REF_NOT_IN_LIST;
+    }
+  }
+
+  iDiagonalRef = iRightTopRef;
+  if (REF_NOT_AVAIL == iDiagonalRef) {
+    iDiagonalRef = iLeftTopRef;
+    * (int32_t*)iMvC = * (int32_t*)iMvD;
+  }
+
+  if (REF_NOT_AVAIL == iTopRef && REF_NOT_AVAIL == iDiagonalRef && iLeftRef >= REF_NOT_IN_LIST) {
+    ST32 (iMvp, LD32 (iMvA));
+    return;
+  }
+
+  iMatchRef = (0 == iLeftRef) + (0 == iTopRef) + (0 == iDiagonalRef);
+  if (1 == iMatchRef) {
+    if (0 == iLeftRef) {
+      ST32 (iMvp, LD32 (iMvA));
+    } else if (0 == iTopRef) {
+      ST32 (iMvp, LD32 (iMvB));
+    } else {
+      ST32 (iMvp, LD32 (iMvC));
+    }
+  } else {
+    iMvp[0] = WelsMedian (iMvA[0], iMvB[0], iMvC[0]);
+    iMvp[1] = WelsMedian (iMvA[1], iMvB[1], iMvC[1]);
+  }
+}
+
+
+
+int32_t AllocLayerData (PDqLayer pDqLayer) {
+
+  pDqLayer->pSliceIdc = (int32_t*) WelsMalloc (pDqLayer->iMbWidth * pDqLayer->iMbHeight * sizeof (int32_t),
+                        "pDqLayer->pSliceIdc");
+  if (pDqLayer->pSliceIdc == NULL)
+    return 1;
+
+  pDqLayer->pMbType = (int8_t*) WelsMalloc (pDqLayer->iMbWidth * pDqLayer->iMbHeight * sizeof (int8_t),
+                      "pDqLayer->pMbType");
+  if (pDqLayer->pMbType == NULL)
+    return 1;
+
+  pDqLayer->pMv[0] = (int16_t (*)[MB_BLOCK4x4_NUM][MV_A]) WelsMalloc (pDqLayer->iMbWidth * pDqLayer->iMbHeight * sizeof (
+                       int16_t) * MV_A * MB_BLOCK4x4_NUM, "pDqLayer->pMv");
+  if (pDqLayer->pMv[0] == NULL)
+    return 1;
+
+  pDqLayer->pRefIndex[0] = (int8_t (*)[MB_BLOCK4x4_NUM]) WelsMalloc (pDqLayer->iMbWidth * pDqLayer->iMbHeight * sizeof (
+                             int8_t) * MB_BLOCK4x4_NUM, "pDqLayer->pRefIndex");
+  if (pDqLayer->pRefIndex[0] == NULL)
+    return 1;
+
+  return 0;
+}
+
+int32_t FreeLayerData (PDqLayer pDqLayer) {
+
+  if (pDqLayer->pSliceIdc != NULL) {
+    WelsFree (pDqLayer->pSliceIdc, "pDqLayer->pSliceIdc");
+    pDqLayer->pSliceIdc = NULL;
+  }
+
+  if (pDqLayer->pMbType != NULL) {
+    WelsFree (pDqLayer->pMbType, "pDqLayer->pMbType");
+    pDqLayer->pMbType = NULL;
+  }
+
+  if (pDqLayer->pMv[0] != NULL) {
+    WelsFree (pDqLayer->pMv[0], "pDqlayer->pMv[0]");
+    pDqLayer->pMv[0] = NULL;
+  }
+
+  if (pDqLayer->pRefIndex[0] != NULL) {
+    WelsFree (pDqLayer->pRefIndex[0], "pDqlayer->pRefIndex[0]");
+    pDqLayer->pRefIndex[0] = NULL;
+  }
+
+  return 0;
+}
+
+void InitRandomLayerSliceIdc (PDqLayer pDqLayer) {
+  srand ((uint32_t)time (NULL));
+  int32_t i = 0;
+  int32_t iTotalMbNum = pDqLayer->iMbWidth * pDqLayer->iMbHeight;
+  int32_t iMbFirstSliceEnd = rand() % (iTotalMbNum - 1); //assure 2 slices
+  for (i = 0; i <= iMbFirstSliceEnd; ++i) {
+    pDqLayer->pSliceIdc[i] = 0; //to keep simple value here
+  }
+  for (; i < iTotalMbNum; ++i) {
+    pDqLayer->pSliceIdc[i] = 1; //to keep simple value here
+  }
+}
+
+void InitRandomLayerMbType (PDqLayer pDqLayer) {
+  srand ((uint32_t)time (NULL));
+  for (int32_t i = 0; i < pDqLayer->iMbWidth * pDqLayer->iMbHeight; ++i) {
+    pDqLayer->pMbType[i] = (rand() & 0x0f) + 1; //1 ~ 16
+  }
+}
+
+void InitRandomLayerMvData (PDqLayer pDqLayer) {
+  srand ((uint32_t)time (NULL));
+  for (int32_t i = 0; i < pDqLayer->iMbWidth * pDqLayer->iMbHeight; ++i) {
+    for (int32_t j = 0; j < MB_BLOCK4x4_NUM; ++j) {
+      for (int32_t k = 0; k < MV_A; ++k) {
+        pDqLayer->pMv[0][i][j][k] = (rand() - RAND_MAX / 2);
+      }
+    }
+  }
+}
+
+void InitRandomLayerRefIdxData (PDqLayer pDqLayer) {
+  srand ((uint32_t)time (NULL));
+  for (int32_t i = 0; i < pDqLayer->iMbWidth * pDqLayer->iMbHeight; ++i) {
+    for (int32_t j = 0; j < MB_BLOCK4x4_NUM; ++j) {
+      pDqLayer->pRefIndex[0][i][j] = (rand() % 18 - 2); //-2 ~ 15
+    }
+  }
+}
+
+void InitRandomLayerData (PDqLayer pDqLayer) {
+  InitRandomLayerSliceIdc (pDqLayer);
+  InitRandomLayerMbType (pDqLayer);
+  InitRandomLayerMvData (pDqLayer);
+  InitRandomLayerRefIdxData (pDqLayer);
+}
+
+#define TEST_SKIP_MV_PRED \
+  PredPSkipMvFromNeighbor (&sDqLayer, iWelsMvp); \
+  bOK = ((iWelsMvp[0] == iAncMvp[0]) && (iWelsMvp[1] == iAncMvp[1])); \
+  EXPECT_EQ (bOK, true);
+
+TEST (PredMvTest, PredSkipMvFromNeighbor) {
+  const int32_t kiRandTime = 100;
+  bool bOK = true;
+  SDqLayer sDqLayer;
+  int16_t iAncMvp[2], iWelsMvp[2];
+
+  memset (&sDqLayer, 0, sizeof (SDqLayer));
+  //Assume the input data as 352x288 size
+  //allocate the data
+  sDqLayer.iMbWidth = 11;
+  sDqLayer.iMbHeight = 9;
+  if (AllocLayerData (&sDqLayer)) { //memory allocate failed
+    FreeLayerData (&sDqLayer);
+    return;
+  }
+  InitRandomLayerData (&sDqLayer); //init MV data, as it would not affect the following logic test
+
+#define CURR_MB_IDX (sDqLayer.iMbXyIndex)
+#define LEFT_MB_IDX (sDqLayer.iMbXyIndex - 1)
+#define LEFT_MB_BLK 3
+#define TOP_MB_IDX (sDqLayer.iMbXyIndex - sDqLayer.iMbWidth)
+#define TOP_MB_BLK 12
+#define LEFT_TOP_MB_IDX (sDqLayer.iMbXyIndex - sDqLayer.iMbWidth - 1)
+#define LEFT_TOP_MB_BLK 15
+#define RIGHT_TOP_MB_IDX (sDqLayer.iMbXyIndex - sDqLayer.iMbWidth + 1)
+#define RIGHT_TOP_MB_BLK 12
+
+  //CASE 1: test MB [0,0], expect mvp = (0,0)
+  sDqLayer.iMbX = 0;
+  sDqLayer.iMbY = 0;
+  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
+  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
+  TEST_SKIP_MV_PRED;
+  //CASE 2: test MB [ANY, 0], expect mvp = (0,0)
+  sDqLayer.iMbX = rand() % sDqLayer.iMbWidth;
+  sDqLayer.iMbY = 0;
+  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
+  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
+  TEST_SKIP_MV_PRED;
+  //CASE 3: test MB [0, ANY], expect mvp = (0,0)
+  sDqLayer.iMbX = 0;
+  sDqLayer.iMbY = rand() % sDqLayer.iMbHeight;
+  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
+  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
+  TEST_SKIP_MV_PRED;
+  //CASE 4.1: test MB [RIGHT_SIDE, ANY]
+  sDqLayer.iMbX = sDqLayer.iMbWidth - 1;
+  sDqLayer.iMbY = rand() % (sDqLayer.iMbHeight - 1) + 1; //not equal to 0
+  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
+  //CASE 4.1.1: same slice_idc, assume = 0
+  memset (sDqLayer.pSliceIdc, 0, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int32_t));
+  //CASE 4.1.1.1: ALL P modes
+  memset (sDqLayer.pMbType, MB_TYPE_16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t));
+  //CASE 4.1.1.1.1: ref_idx = 0, left MV = 0, top MV != 0, expect mvp = (0,0)
+  memset (sDqLayer.pRefIndex[0], 0, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (int8_t));
+  InitRandomLayerMvData (&sDqLayer); //reset Mv data
+  sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][0] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][1] = 0; //left_mv = 0
+  sDqLayer.pMv[0][ TOP_MB_IDX][ TOP_MB_BLK][0] = sDqLayer.pMv[0][ TOP_MB_IDX][ TOP_MB_BLK][1] = 1; //top_mv != 0
+  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
+  TEST_SKIP_MV_PRED;
+  //CASE 4.1.1.1.2: ref_idx = 0, left MV != 0, top MV = 0, expect mvp = (0,0)
+  memset (sDqLayer.pRefIndex[0], 0, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (int8_t));
+  InitRandomLayerMvData (&sDqLayer); //reset Mv data
+  sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][0] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][1] = 1; //left_mv != 0
+  sDqLayer.pMv[0][ TOP_MB_IDX][ TOP_MB_BLK][0] = sDqLayer.pMv[0][ TOP_MB_IDX][ TOP_MB_BLK][1] = 0; //top_mv = 0
+  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
+  TEST_SKIP_MV_PRED;
+  //CASE 4.1.1.1.3: ref_idx top = 0, others = 1, expect mvp = top mv
+  InitRandomLayerMvData (&sDqLayer); //reset Mv data
+  sDqLayer.pRefIndex[0][ TOP_MB_IDX][ TOP_MB_BLK] = 0; //top ref_idx = 0
+  sDqLayer.pRefIndex[0][LEFT_MB_IDX][LEFT_MB_BLK] = 1; //left ref_idx = 1
+  sDqLayer.pRefIndex[0][LEFT_TOP_MB_IDX][LEFT_TOP_MB_BLK] = 1; //left_top ref_idx = 1
+  iAncMvp[0] = sDqLayer.pMv[0][TOP_MB_IDX][TOP_MB_BLK][0];
+  iAncMvp[1] = sDqLayer.pMv[0][TOP_MB_IDX][TOP_MB_BLK][1];
+  TEST_SKIP_MV_PRED;
+  //CASE 4.1.1.1.4: ref_idx left = 0, others = 1, expect mvp = left mv
+  sDqLayer.pRefIndex[0][ TOP_MB_IDX][ TOP_MB_BLK] = 1; //top ref_idx = 1
+  sDqLayer.pRefIndex[0][LEFT_MB_IDX][LEFT_MB_BLK] = 0; //left ref_idx = 0
+  sDqLayer.pRefIndex[0][LEFT_TOP_MB_IDX][LEFT_TOP_MB_BLK] = 1; //left_top ref_idx = 1
+  iAncMvp[0] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][0];
+  iAncMvp[1] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][1];
+  TEST_SKIP_MV_PRED;
+  //CASE 4.1.1.2: All I
+  memset (sDqLayer.pMbType, MB_TYPE_INTRA16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t));
+  //CASE 4.1.1.2.1: left P, expect mvp = left mv
+  sDqLayer.pMbType[LEFT_MB_IDX] = MB_TYPE_16x16; //left P
+  iAncMvp[0] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][0];
+  iAncMvp[1] = sDqLayer.pMv[0][LEFT_MB_IDX][LEFT_MB_BLK][1];
+  TEST_SKIP_MV_PRED;
+  //CASE 4.1.1.3: only top P, top ref_idx = 0, expect mvp = top mv
+  memset (sDqLayer.pMbType, MB_TYPE_INTRA16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t)); // All I MB
+  memset (sDqLayer.pRefIndex[0], 1, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (
+            int8_t)); // All ref_idx = 1
+  sDqLayer.pMbType[TOP_MB_IDX] = MB_TYPE_16x16; //top P
+  sDqLayer.pRefIndex[0][TOP_MB_IDX][TOP_MB_BLK] = 0; //top ref_idx = 0
+  iAncMvp[0] = sDqLayer.pMv[0][TOP_MB_IDX][TOP_MB_BLK][0];
+  iAncMvp[1] = sDqLayer.pMv[0][TOP_MB_IDX][TOP_MB_BLK][1];
+  TEST_SKIP_MV_PRED;
+  //CASE 4.1.1.4: only left_top P, left_top ref_idx = 0, expect mvp = 0
+  sDqLayer.iMbX = (rand() % (sDqLayer.iMbWidth - 2)) + 1; //1 ~ (mb_width - 2)
+  sDqLayer.iMbY = (rand() % (sDqLayer.iMbHeight - 2)) + 1; //1 ~ (mb_height - 2)
+  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
+  memset (sDqLayer.pMbType, MB_TYPE_INTRA16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t)); // All I MB
+  memset (sDqLayer.pRefIndex[0], 1, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (
+            int8_t)); // All ref_idx = 1
+  sDqLayer.pMbType[LEFT_TOP_MB_IDX] = MB_TYPE_16x16; //top P
+  sDqLayer.pRefIndex[0][LEFT_TOP_MB_IDX][LEFT_TOP_MB_BLK] = 0; //top ref_idx = 0
+  iAncMvp[0] = iAncMvp[1] = 0; //expect anchor result to 0
+  TEST_SKIP_MV_PRED;
+  //CASE 4.1.1.5: only right_top P, right_top ref_idx = 0, expect mvp = right_top mv
+  sDqLayer.iMbX = (rand() % (sDqLayer.iMbWidth - 2)) + 1; //1 ~ (mb_width - 2)
+  sDqLayer.iMbY = (rand() % (sDqLayer.iMbHeight - 2)) + 1; //1 ~ (mb_height - 2)
+  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
+  memset (sDqLayer.pMbType, MB_TYPE_INTRA16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t)); // All I MB
+  memset (sDqLayer.pRefIndex[0], 1, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (
+            int8_t)); // All ref_idx = 1
+  sDqLayer.pMbType[RIGHT_TOP_MB_IDX] = MB_TYPE_16x16; //top P
+  sDqLayer.pRefIndex[0][RIGHT_TOP_MB_IDX][RIGHT_TOP_MB_BLK] = 0; //top ref_idx = 0
+  iAncMvp[0] = sDqLayer.pMv[0][RIGHT_TOP_MB_IDX][RIGHT_TOP_MB_BLK][0];
+  iAncMvp[1] = sDqLayer.pMv[0][RIGHT_TOP_MB_IDX][RIGHT_TOP_MB_BLK][1];
+  TEST_SKIP_MV_PRED;
+  //CASE 4.1.2: different neighbor slice idc for all P and ref_idx = 0, expect mvp = 0
+  memset (sDqLayer.pMbType, MB_TYPE_16x16, sDqLayer.iMbWidth * sDqLayer.iMbHeight * sizeof (int8_t)); // All I MB
+  memset (sDqLayer.pRefIndex[0], 0, sDqLayer.iMbWidth * sDqLayer.iMbHeight * MB_BLOCK4x4_NUM * sizeof (
+            int8_t)); // All ref_idx = 1
+  sDqLayer.iMbX = (rand() % (sDqLayer.iMbWidth - 2)) + 1; //1 ~ (mb_width - 2)
+  sDqLayer.iMbY = (rand() % (sDqLayer.iMbHeight - 2)) + 1; //1 ~ (mb_height - 2)
+  sDqLayer.iMbXyIndex = sDqLayer.iMbY * sDqLayer.iMbWidth + sDqLayer.iMbX;
+  sDqLayer.pSliceIdc[CURR_MB_IDX] = 5;
+  sDqLayer.pSliceIdc[LEFT_MB_IDX] = 0;
+  sDqLayer.pSliceIdc[TOP_MB_IDX] = 1;
+  sDqLayer.pSliceIdc[LEFT_TOP_MB_IDX] = 2;
+  sDqLayer.pSliceIdc[RIGHT_TOP_MB_IDX] = 3;
+  iAncMvp[0] = iAncMvp[1] = 0;
+  TEST_SKIP_MV_PRED;
+
+  //add new specific tests here
+
+  //normal tests
+  int32_t i = 0;
+  while (i++ < kiRandTime) {
+    InitRandomLayerData (&sDqLayer); //init MV data, as it would not affect the following logic test
+    AnchorPredPSkipMvFromNeighbor (&sDqLayer, iAncMvp);
+    TEST_SKIP_MV_PRED;
+  }
+
+  FreeLayerData (&sDqLayer);
+}
--- /dev/null
+++ b/test/decoder/targets.mk
@@ -1,0 +1,13 @@
+DECODER_UNITTEST_SRCDIR=test/decoder
+DECODER_UNITTEST_CPP_SRCS=\
+	$(DECODER_UNITTEST_SRCDIR)/DecUT_ExpandPicture.cpp\
+	$(DECODER_UNITTEST_SRCDIR)/DecUT_IdctResAddPred.cpp\
+	$(DECODER_UNITTEST_SRCDIR)/DecUT_IntraPrediction.cpp\
+	$(DECODER_UNITTEST_SRCDIR)/DecUT_PredMv.cpp\
+
+DECODER_UNITTEST_OBJS += $(DECODER_UNITTEST_CPP_SRCS:.cpp=.$(OBJ))
+
+OBJS += $(DECODER_UNITTEST_OBJS)
+$(DECODER_UNITTEST_SRCDIR)/%.$(OBJ): $(DECODER_UNITTEST_SRCDIR)/%.cpp
+	$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(DECODER_UNITTEST_CFLAGS) $(DECODER_UNITTEST_INCLUDES) -c $(CXX_O) $<
+
--- a/test/decoder_test.cpp
+++ /dev/null
@@ -1,100 +1,0 @@
-#include <gtest/gtest.h>
-#include "utils/HashFunctions.h"
-#include "BaseDecoderTest.h"
-
-static void UpdateHashFromPlane(SHA1Context* ctx, const uint8_t* plane,
-    int width, int height, int stride) {
-  for (int i = 0; i < height; i++) {
-    SHA1Input(ctx, plane, width);
-    plane += stride;
-  }
-}
-
-
-class DecoderInitTest : public ::testing::Test, public BaseDecoderTest {
- public:
-  virtual void SetUp() {
-    BaseDecoderTest::SetUp();
-  }
-  virtual void TearDown() {
-    BaseDecoderTest::TearDown();
-  }
-};
-
-TEST_F(DecoderInitTest, JustInit) {}
-
-struct FileParam {
-  const char* fileName;
-  const char* hashStr;
-};
-
-class DecoderOutputTest : public ::testing::WithParamInterface<FileParam>,
-    public DecoderInitTest, public BaseDecoderTest::Callback {
- public:
-  virtual void SetUp() {
-    DecoderInitTest::SetUp();
-    if (HasFatalFailure()) {
-      return;
-    }
-    SHA1Reset(&ctx_);
-  }
-  virtual void onDecodeFrame(const Frame& frame) {
-    const Plane& y = frame.y;
-    const Plane& u = frame.u;
-    const Plane& v = frame.v;
-    UpdateHashFromPlane(&ctx_, y.data, y.width, y.height, y.stride);
-    UpdateHashFromPlane(&ctx_, u.data, u.width, u.height, u.stride);
-    UpdateHashFromPlane(&ctx_, v.data, v.width, v.height, v.stride);
-  }
- protected:
-  SHA1Context ctx_;
-};
-
-TEST_P(DecoderOutputTest, CompareOutput) {
-  FileParam p = GetParam();
-  DecodeFile(p.fileName, this);
-
-  unsigned char digest[SHA_DIGEST_LENGTH];
-  SHA1Result(&ctx_, digest);
-  if (!HasFatalFailure()) {
-    CompareHash(digest, p.hashStr);
-  }
-}
-
-static const FileParam kFileParamArray[] = {
-  {"res/test_vd_1d.264", "5827d2338b79ff82cd091c707823e466197281d3"},
-  {"res/test_vd_rc.264", "eea02e97bfec89d0418593a8abaaf55d02eaa1ca"},
-  {"res/Static.264", "91dd4a7a796805b2cd015cae8fd630d96c663f42"},
-  {"res/BA1_FT_C.264", "418d152fb85709b6f172799dcb239038df437cfa"},
-  {"res/BA1_Sony_D.jsv", "d94b5ceed5686a03ea682b53d415dee999d27eb6"}, 
-  {"res/BAMQ1_JVC_C.264", "613cf662c23e5d9e1d7da7fe880a3c427411d171"},
-  {"res/BAMQ2_JVC_C.264", "11bcf3713f520e606a8326d37e00e5fd6c9fd4a0"},
-  {"res/BA_MW_D.264", "afd7a9765961ca241bb4bdf344b31397bec7465a"},
-  {"res/BANM_MW_D.264", "92d924a857a1a7d7d9b224eaa3887830f15dee7f"},
-  {"res/BASQP1_Sony_C.jsv", "3986c8c9d2876d2f0748b925101b152c6ec8b811"},
-  {"res/CI1_FT_B.264", "cbfec15e17a504678b19a1191992131c92a1ac26"},
-  {"res/CI_MW_D.264", "289f29a103c8d95adf2909c646466904be8b06d7"},
-  {"res/CVFC1_Sony_C.jsv", "4641abd7419a5580b97f16e83fd1d566339229d0"}, 
-  {"res/CVPCMNL1_SVA_C.264", "c2b0d964de727c64b9fccb58f63b567c82bda95a"},
-  {"res/LS_SVA_D.264", "72118f4d1674cf14e58bed7e67cb3aeed3df62b9"},
-  {"res/MIDR_MW_D.264", "9467030f4786f75644bf06a7fc809c36d1959827"},
-  {"res/MPS_MW_A.264", "67f1cfbef0e8025ed60dedccf8d9558d0636be5f"},
-  {"res/MR1_BT_A.h264", "6e585f8359667a16b03e5f49a06f5ceae8d991e0"},
-  {"res/MR1_MW_A.264", "d9e2bf34e9314dcc171ddaea2c5015d0421479f2"},
-  {"res/MR2_MW_A.264", "628b1d4eff04c2d277f7144e23484957dad63cbe"},
-  {"res/MR2_TANDBERG_E.264", "74d618bc7d9d41998edf4c85d51aa06111db6609"},
-  {"res/NL1_Sony_D.jsv", "e401e30669938443c2f02522fd4d5aa1382931a0"},
-  {"res/NLMQ1_JVC_C.264", "f3265c6ddf8db1b2bf604d8a2954f75532e28cda"},
-  {"res/NLMQ2_JVC_C.264", "350ae86ef9ba09390d63a09b7f9ff54184109ca8"},
-  {"res/NRF_MW_E.264", "20732198c04cd2591350a361e4510892f6eed3f0"},
-  {"res/SVA_BA1_B.264", "c4543b24823b16c424c673616c36c7f537089b2d"},
-  {"res/SVA_BA2_D.264", "98ff2d67860462d8d8bcc9352097c06cc401d97e"},
-  {"res/SVA_Base_B.264", "91f514d81cd33de9f6fbf5dbefdb189cc2e7ecf4"},
-  {"res/SVA_CL1_E.264", "4fe09ab6cdc965ea10a20f1d6dd38aca954412bb"},
-  {"res/SVA_FM1_E.264", "fad08c4ff7cf2307b6579853d0f4652fc26645d3"},
-  {"res/SVA_NL1_B.264", "6d63f72a0c0d833b1db0ba438afff3b4180fb3e6"},
-  {"res/SVA_NL2_E.264", "70453ef8097c94dd190d6d2d1d5cb83c67e66238"}
-};
-
-INSTANTIATE_TEST_CASE_P(DecodeFile, DecoderOutputTest,
-    ::testing::ValuesIn(kFileParamArray));
--- /dev/null
+++ b/test/encoder/EncUT_MemoryAlloc.cpp
@@ -1,0 +1,63 @@
+#include <time.h>
+
+#include "gtest/gtest.h"
+#include "memory_align.h"
+
+using namespace WelsSVCEnc;
+
+//Tests of WelsGetCacheLineSize Begin
+TEST(MemoryAlignTest, GetCacheLineSize_LoopWithin16K)
+{
+  const unsigned int kuiTestBoundary16K = 16 * 1024;
+	unsigned int uiTargetAlign = 1;
+	while (uiTargetAlign < kuiTestBoundary16K) {
+		CMemoryAlign cTestMa(uiTargetAlign);
+    ASSERT_EQ(  (uiTargetAlign & 0x0F)?16:uiTargetAlign, cTestMa.WelsGetCacheLineSize() );
+		++ uiTargetAlign;
+	}
+}
+
+TEST(MemoryAlignTest, GetCacheLineSize_Zero)
+{
+  CMemoryAlign cTestMa(0);
+  ASSERT_EQ(  16, cTestMa.WelsGetCacheLineSize() );
+}
+TEST(MemoryAlignTest, GetCacheLineSize_MaxUINT)
+{
+	CMemoryAlign cTestMa(0xFFFFFFFF);
+	ASSERT_EQ( 16, cTestMa.WelsGetCacheLineSize() );
+}
+//Tests of WelsGetCacheLineSize End
+//Tests of WelsMallocAndFree Begin
+TEST(MemoryAlignTest, WelsMallocAndFreeOnceFunctionVerify)
+{
+  const uint32_t kuiTargetAlignSize[4] = {32, 16, 64, 8};
+  srand((uint32_t)time(NULL));
+
+  for (int i=0; i<4; i++) {
+    const uint32_t kuiTestAlignSize	= kuiTargetAlignSize[i];
+    const uint32_t kuiTestDataSize		= abs(rand());
+
+    CMemoryAlign cTestMa(kuiTestAlignSize);
+    const uint32_t uiSize = kuiTestDataSize;
+    const char strUnitTestTag[100] = "pUnitTestData";
+    const uint32_t kuiUsedCacheLineSize	= ((kuiTestAlignSize == 0) || (kuiTestAlignSize & 0x0F)) ? (16) : (kuiTestAlignSize);
+    const uint32_t kuiExtraAlignSize	= kuiUsedCacheLineSize-1;
+    const uint32_t kuiExpectedSize	= sizeof( void ** ) + sizeof( int32_t ) + kuiExtraAlignSize + uiSize;
+    uint8_t *pUnitTestData = static_cast<uint8_t *>(cTestMa.WelsMalloc(uiSize, strUnitTestTag));
+    if ( pUnitTestData != NULL ) {
+      ASSERT_TRUE( (((uintptr_t)(pUnitTestData)) & kuiExtraAlignSize) == 0 );
+      EXPECT_EQ( kuiExpectedSize, cTestMa.WelsGetMemoryUsage() );
+      cTestMa.WelsFree( pUnitTestData, strUnitTestTag );
+      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
+    }
+    else {
+      EXPECT_EQ( NULL, pUnitTestData );
+      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
+      cTestMa.WelsFree( pUnitTestData, strUnitTestTag );
+      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
+    }
+  }
+}
+
+
--- /dev/null
+++ b/test/encoder/EncUT_MotionEstimate.cpp
@@ -1,0 +1,125 @@
+#include <stdlib.h>
+#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; i<kiBlockSize; i++) {
+    memcpy( pSourcePos, pTargetPos, kiBlockSize*sizeof(uint8_t) );
+    pTargetPos += kiRefPicStride;
+    pSourcePos += kiBlockSize;
+  }
+}
+
+
+void InitMe( const uint8_t kuiQp, const uint32_t kuiMvdTableMiddle, const uint32_t kuiMvdTableStride,
+            uint16_t* pMvdCostTable, SWelsME* pMe)
+{
+  MvdCostInit( pMvdCostTable, kuiMvdTableStride );
+  pMe->pMvdCost = &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<uint8_t *>
+    (malloc(m_iWidth*m_iHeight));
+    ASSERT_TRUE( NULL != m_pRefPic );
+    m_pSrcBlock = static_cast<uint8_t *>
+    (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, iTryTimes;
+  for (i=0;i<TEST_POS;i++) {
+    sTargetMv.iMvX = kiPositionToCheck[i][0];
+    sTargetMv.iMvY = kiPositionToCheck[i][1];
+    iTryTimes = 100;
+    bDataGeneratorSucceed = false;
+    bFoundMatch = false;
+    while (!bFoundMatch && (iTryTimes--)>0) {
+      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))||(sMe.sMv.iMvX==0)) && ((sMe.sMv.iMvY==(sTargetMv.iMvY))||(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
+    }
+  }
+}
--- /dev/null
+++ b/test/encoder/targets.mk
@@ -1,0 +1,11 @@
+ENCODER_UNITTEST_SRCDIR=test/encoder
+ENCODER_UNITTEST_CPP_SRCS=\
+	$(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryAlloc.cpp\
+	$(ENCODER_UNITTEST_SRCDIR)/EncUT_MotionEstimate.cpp\
+
+ENCODER_UNITTEST_OBJS += $(ENCODER_UNITTEST_CPP_SRCS:.cpp=.$(OBJ))
+
+OBJS += $(ENCODER_UNITTEST_OBJS)
+$(ENCODER_UNITTEST_SRCDIR)/%.$(OBJ): $(ENCODER_UNITTEST_SRCDIR)/%.cpp
+	$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(ENCODER_UNITTEST_CFLAGS) $(ENCODER_UNITTEST_INCLUDES) -c $(CXX_O) $<
+
--- a/test/encoder_test.cpp
+++ /dev/null
@@ -1,101 +1,0 @@
-#include <gtest/gtest.h>
-#include "utils/HashFunctions.h"
-#include "BaseEncoderTest.h"
-
-static void UpdateHashFromFrame(const SFrameBSInfo& info, SHA1Context* ctx) {
-  for (int i = 0; i < info.iLayerNum; ++i) {
-    const SLayerBSInfo& layerInfo = info.sLayerInfo[i];
-    int layerSize = 0;
-    for (int j = 0; j < layerInfo.iNalCount; ++j) {
-      layerSize += layerInfo.iNalLengthInByte[j];
-    }
-    SHA1Input(ctx, layerInfo.pBsBuf, layerSize);
-  }
-}
-
-class EncoderInitTest : public ::testing::Test, public BaseEncoderTest {
- public:
-  virtual void SetUp() {
-    BaseEncoderTest::SetUp();
-  }
-  virtual void TearDown() {
-    BaseEncoderTest::TearDown();
-  }
-};
-
-TEST_F(EncoderInitTest, JustInit) {}
-
-struct EncodeFileParam {
-  const char* fileName;
-  const char* hashStr;
-  int width;
-  int height;
-  float frameRate;
-  SliceModeEnum slices;
-  bool denoise;
-  int deblocking;
-  int layers;
-};
-
-class EncoderOutputTest : public ::testing::WithParamInterface<EncodeFileParam>,
-    public EncoderInitTest , public BaseEncoderTest::Callback {
- public:
-  virtual void SetUp() {
-    EncoderInitTest::SetUp();
-    if (HasFatalFailure()) {
-      return;
-    }
-    SHA1Reset(&ctx_);
-  }
-  virtual void onEncodeFrame(const SFrameBSInfo& frameInfo) {
-    UpdateHashFromFrame(frameInfo, &ctx_);
-  }
- protected:
-  SHA1Context ctx_;
-};
-
-
-TEST_P(EncoderOutputTest, CompareOutput) {
-  EncodeFileParam p = GetParam();
-  EncodeFile(p.fileName, p.width, p.height, p.frameRate, p.slices, p.denoise, p.deblocking, p.layers, this);
-
-  unsigned char digest[SHA_DIGEST_LENGTH];
-  SHA1Result(&ctx_, digest);
-  if (!HasFatalFailure()) {
-    CompareHash(digest, p.hashStr);
-  }
-}
-
-static const EncodeFileParam kFileParamArray[] = {
-  {
-      "res/CiscoVT2people_320x192_12fps.yuv",
-      "06441376891cbc237a36e59b62131cd94ff9cb19", 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1, 1
-  },
-  {
-      "res/CiscoVT2people_160x96_6fps.yuv",
-      "4f3759fc44125b27a179ebff158dbba9e431bd0b", 160, 96, 6.0f, SM_SINGLE_SLICE, false, 1, 1
-  },
-  {
-      "res/Static_152_100.yuv",
-      "af5c6a41b567ce1b2cb6fd427f4379473d3b829f", 152, 100, 6.0f, SM_SINGLE_SLICE, false, 1, 1
-  },
-  {
-      "res/CiscoVT2people_320x192_12fps.yuv",
-      "be0079b022b18fdce04570db24e4327ca26a0ecb", 320, 192, 12.0f, SM_ROWMB_SLICE, false, 1, 1 // One slice per MB row
-  },
-  {
-      "res/CiscoVT2people_320x192_12fps.yuv",
-      "f4649601ca15f9693671d7e161e9daa8efd3a7a1", 320, 192, 12.0f, SM_SINGLE_SLICE, true, 1, 1
-  },
-  {
-      "res/CiscoVT2people_320x192_12fps.yuv",
-      "e4bcd744d2e6f885f6c0dbe5d52818ba64d986d9", 320, 192, 12.0f, SM_SINGLE_SLICE, false, 0, 1
-  },
-  {
-      "res/CiscoVT2people_320x192_12fps.yuv",
-      "ba81a0f1a14214e6d3c7f1608991b3ac97789370", 320, 192, 12.0f, SM_SINGLE_SLICE, false, 0, 2
-  },
-};
-
-INSTANTIATE_TEST_CASE_P(EncodeFile, EncoderOutputTest,
-    ::testing::ValuesIn(kFileParamArray));
--- a/test/sha1.c
+++ /dev/null
@@ -1,399 +1,0 @@
-/*!
- * \copy
- *     Copyright (c)  1998, 2009 Paul E. Jones <[email protected]>
- *     All rights reserved.
- *
- *     Redistribution and use in source and binary forms, with or without
- *     modification, are permitted provided that the following conditions
- *     are met:
- *
- *        * Redistributions of source code must retain the above copyright
- *          notice, this list of conditions and the following disclaimer.
- *
- *        * Redistributions in binary form must reproduce the above copyright
- *          notice, this list of conditions and the following disclaimer in
- *          the documentation and/or other materials provided with the
- *          distribution.
- *
- *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *     POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/*
- *  Description:
- *      This file implements the Secure Hashing Standard as defined
- *      in FIPS PUB 180-1 published April 17, 1995.
- *
- *      The Secure Hashing Standard, which uses the Secure Hashing
- *      Algorithm (SHA), produces a 160-bit message digest for a
- *      given data stream.  In theory, it is highly improbable that
- *      two messages will produce the same message digest.  Therefore,
- *      this algorithm can serve as a means of providing a "fingerprint"
- *      for a message.
- *
- *  Portability Issues:
- *      SHA-1 is defined in terms of 32-bit "words".  This code was
- *      written with the expectation that the processor has at least
- *      a 32-bit machine word size.  If the machine word size is larger,
- *      the code should still function properly.  One caveat to that
- *      is that the input functions taking characters and character
- *      arrays assume that only 8 bits of information are stored in each
- *      character.
- *
- *  Caveats:
- *      SHA-1 is designed to work with messages less than 2^64 bits
- *      long. Although SHA-1 allows a message digest to be generated for
- *      messages of any number of bits less than 2^64, this
- *      implementation only works with messages with a length that is a
- *      multiple of the size of an 8-bit character.
- *
- */
-
-#include "sha1.h"
-
-/*
- *  Define the circular shift macro
- */
-#define SHA1CircularShift(bits,word) \
-                ((((word) << (bits)) & 0xFFFFFFFF) | \
-                ((word) >> (32-(bits))))
-
-/* Function prototypes */
-void SHA1ProcessMessageBlock(SHA1Context *);
-void SHA1PadMessage(SHA1Context *);
-
-/*
- *  SHA1Reset
- *
- *  Description:
- *      This function will initialize the SHA1Context in preparation
- *      for computing a new message digest.
- *
- *  Parameters:
- *      context: [in/out]
- *          The context to reset.
- *
- *  Returns:
- *      Nothing.
- *
- *  Comments:
- *
- */
-void SHA1Reset(SHA1Context *context)
-{
-    context->Length_Low             = 0;
-    context->Length_High            = 0;
-    context->Message_Block_Index    = 0;
-
-    context->Message_Digest[0]      = 0x67452301;
-    context->Message_Digest[1]      = 0xEFCDAB89;
-    context->Message_Digest[2]      = 0x98BADCFE;
-    context->Message_Digest[3]      = 0x10325476;
-    context->Message_Digest[4]      = 0xC3D2E1F0;
-
-    context->Computed   = 0;
-    context->Corrupted  = 0;
-}
-
-/*
- *  SHA1Result
- *
- *  Description:
- *      This function will return the 160-bit message digest into the
- *      digest array provided as a parameter.
- *
- *  Parameters:
- *      context: [in/out]
- *          The context to use to calculate the SHA-1 hash.
- *      digest: [out]
- *          An array of characters where the digest is written.
- *
- *  Returns:
- *      1 if successful, 0 if it failed.
- *
- *  Comments:
- *
- */
-int SHA1Result(SHA1Context *context, unsigned char *digest)
-{
-    int i;
-
-    if (context->Corrupted)
-    {
-        return 0;
-    }
-
-    if (!context->Computed)
-    {
-        SHA1PadMessage(context);
-        context->Computed = 1;
-    }
-
-    for (i = 0; i < SHA_DIGEST_LENGTH; i++)
-        digest[i] = context->Message_Digest[i / 4] >> (8 * (3 - (i % 4)));
-
-    return 1;
-}
-
-/*
- *  SHA1Input
- *
- *  Description:
- *      This function accepts an array of octets as the next portion of
- *      the message.
- *
- *  Parameters:
- *      context: [in/out]
- *          The SHA-1 context to update
- *      message_array: [in]
- *          An array of characters representing the next portion of the
- *          message.
- *      length: [in]
- *          The length of the message in message_array
- *
- *  Returns:
- *      Nothing.
- *
- *  Comments:
- *
- */
-void SHA1Input(     SHA1Context         *context,
-                    const unsigned char *message_array,
-                    unsigned            length)
-{
-    if (!length)
-    {
-        return;
-    }
-
-    if (context->Computed || context->Corrupted)
-    {
-        context->Corrupted = 1;
-        return;
-    }
-
-    while(length-- && !context->Corrupted)
-    {
-        context->Message_Block[context->Message_Block_Index++] =
-                                                (*message_array & 0xFF);
-
-        context->Length_Low += 8;
-        /* Force it to 32 bits */
-        context->Length_Low &= 0xFFFFFFFF;
-        if (context->Length_Low == 0)
-        {
-            context->Length_High++;
-            /* Force it to 32 bits */
-            context->Length_High &= 0xFFFFFFFF;
-            if (context->Length_High == 0)
-            {
-                /* Message is too long */
-                context->Corrupted = 1;
-            }
-        }
-
-        if (context->Message_Block_Index == 64)
-        {
-            SHA1ProcessMessageBlock(context);
-        }
-
-        message_array++;
-    }
-}
-
-/*
- *  SHA1ProcessMessageBlock
- *
- *  Description:
- *      This function will process the next 512 bits of the message
- *      stored in the Message_Block array.
- *
- *  Parameters:
- *      None.
- *
- *  Returns:
- *      Nothing.
- *
- *  Comments:
- *      Many of the variable names in the SHAContext, especially the
- *      single character names, were used because those were the names
- *      used in the publication.
- *
- *
- */
-void SHA1ProcessMessageBlock(SHA1Context *context)
-{
-    const unsigned K[] =            /* Constants defined in SHA-1   */
-    {
-        0x5A827999,
-        0x6ED9EBA1,
-        0x8F1BBCDC,
-        0xCA62C1D6
-    };
-    int         t;                  /* Loop counter                 */
-    unsigned    temp;               /* Temporary word value         */
-    unsigned    W[80];              /* Word sequence                */
-    unsigned    A, B, C, D, E;      /* Word buffers                 */
-
-    /*
-     *  Initialize the first 16 words in the array W
-     */
-    for(t = 0; t < 16; t++)
-    {
-        W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
-        W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
-        W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
-        W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
-    }
-
-    for(t = 16; t < 80; t++)
-    {
-       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
-    }
-
-    A = context->Message_Digest[0];
-    B = context->Message_Digest[1];
-    C = context->Message_Digest[2];
-    D = context->Message_Digest[3];
-    E = context->Message_Digest[4];
-
-    for(t = 0; t < 20; t++)
-    {
-        temp =  SHA1CircularShift(5,A) +
-                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
-        temp &= 0xFFFFFFFF;
-        E = D;
-        D = C;
-        C = SHA1CircularShift(30,B);
-        B = A;
-        A = temp;
-    }
-
-    for(t = 20; t < 40; t++)
-    {
-        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
-        temp &= 0xFFFFFFFF;
-        E = D;
-        D = C;
-        C = SHA1CircularShift(30,B);
-        B = A;
-        A = temp;
-    }
-
-    for(t = 40; t < 60; t++)
-    {
-        temp = SHA1CircularShift(5,A) +
-               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
-        temp &= 0xFFFFFFFF;
-        E = D;
-        D = C;
-        C = SHA1CircularShift(30,B);
-        B = A;
-        A = temp;
-    }
-
-    for(t = 60; t < 80; t++)
-    {
-        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
-        temp &= 0xFFFFFFFF;
-        E = D;
-        D = C;
-        C = SHA1CircularShift(30,B);
-        B = A;
-        A = temp;
-    }
-
-    context->Message_Digest[0] =
-                        (context->Message_Digest[0] + A) & 0xFFFFFFFF;
-    context->Message_Digest[1] =
-                        (context->Message_Digest[1] + B) & 0xFFFFFFFF;
-    context->Message_Digest[2] =
-                        (context->Message_Digest[2] + C) & 0xFFFFFFFF;
-    context->Message_Digest[3] =
-                        (context->Message_Digest[3] + D) & 0xFFFFFFFF;
-    context->Message_Digest[4] =
-                        (context->Message_Digest[4] + E) & 0xFFFFFFFF;
-
-    context->Message_Block_Index = 0;
-}
-
-/*
- *  SHA1PadMessage
- *
- *  Description:
- *      According to the standard, the message must be padded to an even
- *      512 bits.  The first padding bit must be a '1'.  The last 64
- *      bits represent the length of the original message.  All bits in
- *      between should be 0.  This function will pad the message
- *      according to those rules by filling the Message_Block array
- *      accordingly.  It will also call SHA1ProcessMessageBlock()
- *      appropriately.  When it returns, it can be assumed that the
- *      message digest has been computed.
- *
- *  Parameters:
- *      context: [in/out]
- *          The context to pad
- *
- *  Returns:
- *      Nothing.
- *
- *  Comments:
- *
- */
-void SHA1PadMessage(SHA1Context *context)
-{
-    /*
-     *  Check to see if the current message block is too small to hold
-     *  the initial padding bits and length.  If so, we will pad the
-     *  block, process it, and then continue padding into a second
-     *  block.
-     */
-    if (context->Message_Block_Index > 55)
-    {
-        context->Message_Block[context->Message_Block_Index++] = 0x80;
-        while(context->Message_Block_Index < 64)
-        {
-            context->Message_Block[context->Message_Block_Index++] = 0;
-        }
-
-        SHA1ProcessMessageBlock(context);
-
-        while(context->Message_Block_Index < 56)
-        {
-            context->Message_Block[context->Message_Block_Index++] = 0;
-        }
-    }
-    else
-    {
-        context->Message_Block[context->Message_Block_Index++] = 0x80;
-        while(context->Message_Block_Index < 56)
-        {
-            context->Message_Block[context->Message_Block_Index++] = 0;
-        }
-    }
-
-    /*
-     *  Store the message length as the last 8 octets
-     */
-    context->Message_Block[56] = (context->Length_High >> 24) & 0xFF;
-    context->Message_Block[57] = (context->Length_High >> 16) & 0xFF;
-    context->Message_Block[58] = (context->Length_High >> 8) & 0xFF;
-    context->Message_Block[59] = (context->Length_High) & 0xFF;
-    context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF;
-    context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF;
-    context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF;
-    context->Message_Block[63] = (context->Length_Low) & 0xFF;
-
-    SHA1ProcessMessageBlock(context);
-}
--- a/test/simple_test.cpp
+++ /dev/null
@@ -1,7 +1,0 @@
-#include <gtest/gtest.h>
-
-int main (int argc, char** argv) {
-  testing::InitGoogleTest (&argc, argv);
-
-  return RUN_ALL_TESTS();
-}
--- a/test/targets.mk
+++ /dev/null
@@ -1,37 +1,0 @@
-CODEC_UNITTEST_SRCDIR=test
-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)/DecUT_ExpandPicture.cpp\
-	$(CODEC_UNITTEST_SRCDIR)/DecUT_IdctResAddPred.cpp\
-	$(CODEC_UNITTEST_SRCDIR)/DecUT_IntraPrediction.cpp\
-	$(CODEC_UNITTEST_SRCDIR)/DecUT_PredMv.cpp\
-	$(CODEC_UNITTEST_SRCDIR)/encoder_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=.$(OBJ))
-
-CODEC_UNITTEST_C_SRCS=\
-	$(CODEC_UNITTEST_SRCDIR)/c_interface_test.c\
-	$(CODEC_UNITTEST_SRCDIR)/sha1.c\
-
-CODEC_UNITTEST_OBJS += $(CODEC_UNITTEST_C_SRCS:.c=.$(OBJ))
-
-OBJS += $(CODEC_UNITTEST_OBJS)
-$(CODEC_UNITTEST_SRCDIR)/%.$(OBJ): $(CODEC_UNITTEST_SRCDIR)/%.cpp
-	$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(CODEC_UNITTEST_CFLAGS) $(CODEC_UNITTEST_INCLUDES) -c $(CXX_O) $<
-
-$(CODEC_UNITTEST_SRCDIR)/%.$(OBJ): $(CODEC_UNITTEST_SRCDIR)/%.c
-	$(QUIET_CC)$(CC) $(CFLAGS) $(INCLUDES) $(CODEC_UNITTEST_CFLAGS) $(CODEC_UNITTEST_INCLUDES) -c $(CXX_O) $<
-
-codec_unittest$(EXEEXT): $(CODEC_UNITTEST_OBJS) $(LIBS) $(CODEC_UNITTEST_LIBS) $(CODEC_UNITTEST_DEPS)
-	$(QUIET_CXX)$(CXX) $(CXX_LINK_O) $(CODEC_UNITTEST_OBJS) $(CODEC_UNITTEST_LDFLAGS) $(CODEC_UNITTEST_LIBS) $(LDFLAGS) $(LIBS)
-
-binaries: codec_unittest$(EXEEXT)
-BINARIES += codec_unittest$(EXEEXT)