660 lines · 22.8 KB · C++
RawDownload
#include <gtest/gtest.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 30const 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 testtypedef 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 datavoid AssignMvInputData (SAnchorMvPred* pAncMvPred) {  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) {        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 (SWelsMvPred* pDstMvPred, SAnchorMvPred* 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 (&sWelsMvPred, &sAncMvPred); #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;  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;  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;  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 = 0;   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) {  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) {  for (int32_t i = 0; i < pDqLayer->iMbWidth * pDqLayer->iMbHeight; ++i) {    pDqLayer->pMbType[i] = (rand() & 0x0f) + 1; //1 ~ 16  }} void InitRandomLayerMvData (PDqLayer pDqLayer) {  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) {  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    }  }} 

Lines 1–500 of 660.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t