History

Merge pull request #742 from huili2/ec_ut_copy

add slice/frame copy UT for EC

Licai Guo committed 12 years ago

Commit d905d6b2 parents c4ab780 4a6259c2 files · +292 −0Browse files

Unified · Split

2 files
  1. test/decoder/DecUT_ErrorConcealment.cpp +291 −0
  2. test/decoder/targets.mk +1 −0
test/decoder/DecUT_ErrorConcealment.cpp+291−0
@@ -0,0 +1,291 @@
1+#include<gtest/gtest.h>
2+#include <stdlib.h>
3+#include <time.h>
4+
5+#include "wels_common_basis.h"
6+#include "mem_align.h"
7+#include "error_concealment.h"
8+#include "ls_defines.h"
9+#include "cpu.h"
10+
11+using namespace WelsDec;
12+
13+#define MAX_MB_WIDTH 260
14+#define MAX_MB_HEIGHT 130
15+
16+typedef struct TagECInputCtx {
17+ int32_t iMbWidth;
18+ int32_t iMbHeight;
19+ uint32_t iLinesize[3];
20+ bool* pMbCorrectlyDecodedFlag; //actual memory
21+ PWelsDecoderContext pCtx;
22+ SDqLayer sDqLayer;
23+ SPicture sAncPic; //Anc picture for comparison
24+ SPicture sSrcPic; //Src picture as common input picture data
25+ SPicture sWelsPic; //Wels picture to be compared
26+} SECInputCtx, *PECInputCtx;
27+
28+void FreeInputData (PECInputCtx pECCtx) {
29+ if (pECCtx != NULL) {
30+ if (pECCtx->pCtx != NULL) {
31+ WELS_SAFE_FREE (pECCtx->pCtx->pSps, "pECCtx->pCtx->pSps");
32+ WELS_SAFE_FREE (pECCtx->pCtx, "pECCtx->pCtx");
33+ }
34+
35+ WELS_SAFE_FREE (pECCtx->pMbCorrectlyDecodedFlag, "pECCtx->pMbCorrectlyDecodedFlag");
36+ WELS_SAFE_FREE (pECCtx->sSrcPic.pData[0], "pECCtx->sSrcPic.pData");
37+ WELS_SAFE_FREE (pECCtx->sAncPic.pData[0], "pECCtx->sAncPic.pData");
38+ WELS_SAFE_FREE (pECCtx->sWelsPic.pData[0], "pECCtx->sWelsPic.pData");
39+
40+ WELS_SAFE_FREE (pECCtx, "pECCtx");
41+ }
42+}
43+
44+int32_t InitAndAllocInputData (PECInputCtx& pECCtx) {
45+ FreeInputData (pECCtx);
46+
47+ pECCtx = (PECInputCtx) WelsMalloc (sizeof (SECInputCtx), "pECCtx");
48+ if (pECCtx == NULL)
49+ return 1;
50+ memset (pECCtx, 0, sizeof (SECInputCtx));
51+
52+ srand ((uint32_t)time (NULL));
53+ pECCtx->iMbWidth = rand() % MAX_MB_WIDTH; //give a constrained max width
54+ pECCtx->iMbHeight = rand() % MAX_MB_HEIGHT; //give a constrained max height
55+ pECCtx->iLinesize[0] = pECCtx->iMbWidth << 4;
56+ pECCtx->iLinesize[1] = pECCtx->iLinesize[2] = pECCtx->iLinesize[0] >> 1;
57+
58+ const uint32_t kiLumaSize = pECCtx->iMbWidth * pECCtx->iMbHeight * 256;
59+
60+ //allocate picture data
61+ pECCtx->sWelsPic.pData[0] = (uint8_t*) WelsMalloc (kiLumaSize * 3 / 2 * sizeof (uint8_t), "pECCtx->sWelsPic.pData");
62+ if (pECCtx->sWelsPic.pData[0] == NULL)
63+ return 1;
64+ pECCtx->sWelsPic.pData[1] = pECCtx->sWelsPic.pData[0] + kiLumaSize;
65+ pECCtx->sWelsPic.pData[2] = pECCtx->sWelsPic.pData[1] + (kiLumaSize >> 2);
66+
67+ pECCtx->sAncPic.pData[0] = (uint8_t*) WelsMalloc (kiLumaSize * 3 / 2 * sizeof (uint8_t), "pECCtx->sAncPic.pData");
68+ if (pECCtx->sAncPic.pData[0] == NULL)
69+ return 1;
70+ pECCtx->sAncPic.pData[1] = pECCtx->sAncPic.pData[0] + kiLumaSize;
71+ pECCtx->sAncPic.pData[2] = pECCtx->sAncPic.pData[1] + (kiLumaSize >> 2);
72+
73+ pECCtx->sSrcPic.pData[0] = (uint8_t*) WelsMalloc (kiLumaSize * 3 / 2 * sizeof (uint8_t), "pECCtx->sSrcPic.pData");
74+ if (pECCtx->sAncPic.pData[0] == NULL)
75+ return 1;
76+ pECCtx->sSrcPic.pData[1] = pECCtx->sSrcPic.pData[0] + kiLumaSize;
77+ pECCtx->sSrcPic.pData[2] = pECCtx->sSrcPic.pData[1] + (kiLumaSize >> 2);
78+
79+ pECCtx->sWelsPic.iLinesize[0] = pECCtx->sAncPic.iLinesize[0] = pECCtx->sSrcPic.iLinesize[0] = pECCtx->iLinesize[0];
80+ pECCtx->sWelsPic.iLinesize[1] = pECCtx->sAncPic.iLinesize[1] = pECCtx->sSrcPic.iLinesize[1] = pECCtx->iLinesize[1];
81+ pECCtx->sWelsPic.iLinesize[2] = pECCtx->sAncPic.iLinesize[2] = pECCtx->sSrcPic.iLinesize[2] = pECCtx->iLinesize[2];
82+
83+ pECCtx->pMbCorrectlyDecodedFlag = (bool*) WelsMalloc (pECCtx->iMbWidth * pECCtx->iMbHeight * sizeof (bool),
84+ "pECCtx->pMbCorrectlyDecodedFlag");
85+ if (pECCtx->pMbCorrectlyDecodedFlag == NULL)
86+ return 1;
87+
88+ pECCtx->pCtx = (PWelsDecoderContext) WelsMalloc (sizeof (SWelsDecoderContext), "pECCtx->pCtx");
89+ if (pECCtx->pCtx == NULL)
90+ return 1;
91+
92+ pECCtx->pCtx->pDec = &pECCtx->sWelsPic;
93+ pECCtx->pCtx->pCurDqLayer = &pECCtx->sDqLayer;
94+ pECCtx->pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag = pECCtx->pMbCorrectlyDecodedFlag;
95+
96+ pECCtx->pCtx->pSps = (PSps) WelsMalloc (sizeof (SSps), "pECCtx->pCtx->pSps");
97+ if (pECCtx->pCtx->pSps == NULL)
98+ return 1;
99+ pECCtx->pCtx->pSps->iMbWidth = pECCtx->iMbWidth;
100+ pECCtx->pCtx->pSps->iMbHeight = pECCtx->iMbHeight;
101+
102+ return 0;
103+}
104+
105+void InitECCopyData (PECInputCtx pECCtx) {
106+ srand ((uint32_t)time (NULL));
107+ const int32_t kiMbNum = pECCtx->iMbWidth * pECCtx->iMbHeight;
108+ int i;
109+ //init pMbCorrectlyDecodedFlag
110+ for (i = 0; i < kiMbNum; ++i) {
111+ pECCtx->pMbCorrectlyDecodedFlag[i] = !! (rand() & 1);
112+ }
113+ //init Data
114+ const int32_t iPixNum = kiMbNum * 256 * 3 / 2;
115+ for (i = 0; i < iPixNum; ++i) {
116+ pECCtx->sSrcPic.pData[0][i] = rand() & 0xff;
117+ }
118+ int32_t iCpuCores = 1;
119+ pECCtx->pCtx->uiCpuFlag = WelsCPUFeatureDetect (&iCpuCores);
120+ InitErrorCon (pECCtx->pCtx);
121+}
122+
123+void DoAncErrorConSliceCopy (PECInputCtx pECCtx) {
124+ int32_t iMbWidth = (int32_t) pECCtx->iMbWidth;
125+ int32_t iMbHeight = (int32_t) pECCtx->iMbHeight;
126+ PPicture pDstPic = &pECCtx->sAncPic;
127+ PPicture pSrcPic = pECCtx->pCtx->pPreviousDecodedPictureInDpb;
128+
129+ //uint8_t *pDstData[3], *pSrcData[3];
130+ bool* pMbCorrectlyDecodedFlag = pECCtx->pMbCorrectlyDecodedFlag;
131+
132+ //Do slice copy late
133+ int32_t iMbXyIndex, i;
134+ uint8_t* pSrcData, *pDstData;
135+ uint32_t iSrcStride = pECCtx->iLinesize[0];
136+ uint32_t iDstStride = pECCtx->iLinesize[0];
137+ for (int32_t iMbY = 0; iMbY < iMbHeight; ++iMbY) {
138+ for (int32_t iMbX = 0; iMbX < iMbWidth; ++iMbX) {
139+ iMbXyIndex = iMbY * iMbWidth + iMbX;
140+ if (!pMbCorrectlyDecodedFlag[iMbXyIndex]) {
141+ if (pSrcPic != NULL) {
142+ //Y component
143+ pDstData = pDstPic->pData[0] + iMbY * 16 * iDstStride + iMbX * 16;
144+ pSrcData = pSrcPic->pData[0] + iMbY * 16 * iSrcStride + iMbX * 16;
145+ for (i = 0; i < 16; ++i) {
146+ memcpy (pDstData, pSrcData, 16);
147+ pDstData += iDstStride;
148+ pSrcData += iSrcStride;
149+ }
150+ //U component
151+ pDstData = pDstPic->pData[1] + iMbY * 8 * iDstStride / 2 + iMbX * 8;
152+ pSrcData = pSrcPic->pData[1] + iMbY * 8 * iSrcStride / 2 + iMbX * 8;
153+ for (i = 0; i < 8; ++i) {
154+ memcpy (pDstData, pSrcData, 8);
155+ pDstData += iDstStride;
156+ pSrcData += iSrcStride;
157+ }
158+ //V component
159+ pDstData = pDstPic->pData[2] + iMbY * 8 * iDstStride / 2 + iMbX * 8;
160+ pSrcData = pSrcPic->pData[2] + iMbY * 8 * iSrcStride / 2 + iMbX * 8;
161+ for (i = 0; i < 8; ++i) {
162+ memcpy (pDstData, pSrcData, 8);
163+ pDstData += iDstStride;
164+ pSrcData += iSrcStride;
165+ }
166+ } else { //pSrcPic == NULL
167+ //Y component
168+ pDstData = pDstPic->pData[0] + iMbY * 16 * iDstStride + iMbX * 16;
169+ for (int32_t i = 0; i < 16; ++i) {
170+ memset (pDstData, 0, 16);
171+ pDstData += iDstStride;
172+ }
173+ //U component
174+ pDstData = pDstPic->pData[1] + iMbY * 8 * iDstStride / 2 + iMbX * 8;
175+ for (int32_t i = 0; i < 8; ++i) {
176+ memset (pDstData, 0, 8);
177+ pDstData += iDstStride / 2;
178+ }
179+ //V component
180+ pDstData = pDstPic->pData[2] + iMbY * 8 * iDstStride / 2 + iMbX * 8;
181+ for (int32_t i = 0; i < 8; ++i) {
182+ memset (pDstData, 0, 8);
183+ pDstData += iDstStride / 2;
184+ }
185+ } //
186+ } //!pMbCorrectlyDecodedFlag[iMbXyIndex]
187+ } //iMbX
188+ } //iMbY
189+}
190+
191+
192+
193+bool ComparePictureDataI420 (uint8_t* pSrcData, uint8_t* pDstData, const uint32_t kiStride, const int32_t kiHeight) {
194+ bool bSame = true;
195+ uint8_t* pAncData; // = pECCtx->sAncPic.pData[0];
196+ uint8_t* pCompData;
197+ int32_t iStride;
198+ int32_t iCurHeight;
199+ int32_t iHeight = kiHeight;
200+
201+ //Y component
202+ iStride = kiStride;
203+ pAncData = pSrcData;
204+ pCompData = pDstData;
205+ for (iCurHeight = 0; bSame && (iCurHeight < kiHeight); ++iCurHeight) {
206+ bSame = (memcmp (pAncData, pCompData, iStride * sizeof (uint8_t)) == 0);
207+ pAncData += iStride;
208+ pCompData += iStride;
209+ }
210+ //chroma component
211+ iHeight >>= 1;
212+ iStride >>= 1;
213+ //U component
214+ for (iCurHeight = 0; bSame && (iCurHeight < kiHeight / 2); ++iCurHeight) {
215+ bSame = (memcmp (pAncData, pCompData, iStride * sizeof (uint8_t)) == 0);
216+ pAncData += iStride;
217+ pCompData += iStride;
218+ }
219+ //V component
220+ for (iCurHeight = 0; bSame && (iCurHeight < kiHeight / 2); ++iCurHeight) {
221+ bSame = (memcmp (pAncData, pCompData, iStride * sizeof (uint8_t)) == 0);
222+ pAncData += iStride;
223+ pCompData += iStride;
224+ }
225+
226+ return bSame;
227+}
228+
229+//TEST cases followed
230+TEST (ErrorConTest, DoErrorConFrameCopy) {
231+ bool bOK = true;
232+ PECInputCtx pECCtx = NULL;
233+ if (InitAndAllocInputData (pECCtx)) {
234+ FreeInputData (pECCtx);
235+ return;
236+ }
237+
238+ pECCtx->pCtx->iErrorConMethod = ERROR_CON_FRAME_COPY;
239+ InitECCopyData (pECCtx);
240+ //case 1: no reference picture
241+ pECCtx->pCtx->pPreviousDecodedPictureInDpb = NULL;
242+ DoErrorConFrameCopy (pECCtx->pCtx);
243+
244+ int32_t iLumaSize = pECCtx->iMbWidth * pECCtx->iMbHeight * 256;
245+ memset (pECCtx->sAncPic.pData[0], 0, iLumaSize * 3 / 2); //should be the same as known EC method, here all 0
246+ bOK = ComparePictureDataI420 (pECCtx->sAncPic.pData[0], pECCtx->sWelsPic.pData[0], pECCtx->iLinesize[0],
247+ pECCtx->iMbHeight * 16);
248+ EXPECT_EQ (bOK, true);
249+
250+ //case 2: with reference picture
251+ pECCtx->pCtx->pPreviousDecodedPictureInDpb = &pECCtx->sSrcPic;
252+ DoErrorConFrameCopy (pECCtx->pCtx);
253+
254+ memcpy (pECCtx->sAncPic.pData[0], pECCtx->sSrcPic.pData[0], iLumaSize * 3 / 2);
255+ bOK = ComparePictureDataI420 (pECCtx->sAncPic.pData[0], pECCtx->sWelsPic.pData[0], pECCtx->iLinesize[0],
256+ pECCtx->iMbHeight * 16);
257+ EXPECT_EQ (bOK, true);
258+
259+ FreeInputData (pECCtx);
260+}
261+
262+//TEST cases followed
263+TEST (ErrorConTest, DoErrorConSliceCopy) {
264+ bool bOK = true;
265+ PECInputCtx pECCtx = NULL;
266+ if (InitAndAllocInputData (pECCtx)) {
267+ FreeInputData (pECCtx);
268+ return;
269+ }
270+ pECCtx->pCtx->iErrorConMethod = ERROR_CON_SLICE_COPY;
271+ InitECCopyData (pECCtx);
272+ //case 1: no reference picture
273+ pECCtx->pCtx->pPreviousDecodedPictureInDpb = NULL;
274+ DoAncErrorConSliceCopy (pECCtx);
275+ DoErrorConSliceCopy (pECCtx->pCtx);
276+
277+ bOK = ComparePictureDataI420 (pECCtx->sAncPic.pData[0], pECCtx->sWelsPic.pData[0], pECCtx->iLinesize[0],
278+ pECCtx->iMbHeight * 16);
279+ EXPECT_EQ (bOK, true);
280+
281+ //case 2: with reference picture
282+ pECCtx->pCtx->pPreviousDecodedPictureInDpb = &pECCtx->sAncPic;
283+ DoAncErrorConSliceCopy (pECCtx);
284+ DoErrorConSliceCopy (pECCtx->pCtx);
285+
286+ bOK = ComparePictureDataI420 (pECCtx->sAncPic.pData[0], pECCtx->sWelsPic.pData[0], pECCtx->iLinesize[0],
287+ pECCtx->iMbHeight * 16);
288+ EXPECT_EQ (bOK, true);
289+
290+ FreeInputData (pECCtx);
291+}
test/decoder/targets.mk+1−0
@@ -1,5 +1,6 @@
11 DECODER_UNITTEST_SRCDIR=test/decoder
22 DECODER_UNITTEST_CPP_SRCS=\
3+ $(DECODER_UNITTEST_SRCDIR)/DecUT_ErrorConcealment.cpp\
34 $(DECODER_UNITTEST_SRCDIR)/DecUT_ExpandPicture.cpp\
45 $(DECODER_UNITTEST_SRCDIR)/DecUT_IdctResAddPred.cpp\
56 $(DECODER_UNITTEST_SRCDIR)/DecUT_IntraPrediction.cpp\

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