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 (¶m, 0, sizeof(SEncParamBase));
-
- param.fMaxFrameRate = frameRate;
- param.iPicWidth = width;
- param.iPicHeight = height;
- param.iTargetBitrate = 5000000;
- param.iInputCsp = videoFormatI420;
-
- return encoder->Initialize(¶m);
- } else {
- SEncParamExt param;
- encoder->GetDefaultParams(¶m);
-
- 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(¶m);
- }
-}
-
-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 (¶m, 0, sizeof(SEncParamBase));
+
+ param.fMaxFrameRate = frameRate;
+ param.iPicWidth = width;
+ param.iPicHeight = height;
+ param.iTargetBitrate = 5000000;
+ param.iInputCsp = videoFormatI420;
+
+ return encoder->Initialize(¶m);
+ } else {
+ SEncParamExt param;
+ encoder->GetDefaultParams(¶m);
+
+ 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(¶m);
+ }
+}
+
+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)