1 #include <gtest/gtest.h>
2 #include "codec_def.h"
3 #include "expand_pic.h"
4 #include "memory_align.h"
5 #include "cpu.h"
6 #include "cpu_core.h"
7 #include "macros.h"
8 #include "wels_const_common.h"
9
10 #define EXPAND_PIC_TEST_NUM 10
11 #define H264_PADDING_LENGTH_LUMA (PADDING_LENGTH)
12 #define H264_PADDING_LENGTH_CHROMA (PADDING_LENGTH>>1)
13
14 using namespace WelsCommon;
15
H264ExpandPictureLumaAnchor_c(uint8_t * pDst,int32_t iStride,int32_t iPicWidth,int32_t iPicHeight)16 void H264ExpandPictureLumaAnchor_c (uint8_t* pDst, int32_t iStride, int32_t iPicWidth, int32_t iPicHeight) {
17 uint8_t* pTmp = pDst;
18 uint8_t* pDstLastLine = pTmp + (iPicHeight - 1) * iStride;
19 uint8_t pTL = pTmp[0];
20 uint8_t pTR = pTmp[iPicWidth - 1];
21 uint8_t pBL = pDstLastLine[0];
22 uint8_t pBR = pDstLastLine[iPicWidth - 1];
23 int32_t i = 0;
24
25 do {
26 const int32_t kStrides = (1 + i) * iStride;
27 uint8_t* pTop = pTmp - kStrides;
28 uint8_t* pBottom = pDstLastLine + kStrides;
29
30 // pad pTop and pBottom
31 memcpy (pTop, pTmp, iPicWidth);
32 memcpy (pBottom, pDstLastLine, iPicWidth);
33
34 // pad corners
35 memset (pTop - H264_PADDING_LENGTH_LUMA, pTL, H264_PADDING_LENGTH_LUMA); //pTop left
36 memset (pTop + iPicWidth, pTR, H264_PADDING_LENGTH_LUMA); //pTop right
37 memset (pBottom - H264_PADDING_LENGTH_LUMA, pBL, H264_PADDING_LENGTH_LUMA); //pBottom left
38 memset (pBottom + iPicWidth, pBR, H264_PADDING_LENGTH_LUMA); //pBottom right
39 ++ i;
40 } while (i < H264_PADDING_LENGTH_LUMA);
41
42 // pad left and right
43 i = 0;
44 do {
45 memset (pTmp - H264_PADDING_LENGTH_LUMA, pTmp[0], H264_PADDING_LENGTH_LUMA);
46 memset (pTmp + iPicWidth, pTmp[iPicWidth - 1], H264_PADDING_LENGTH_LUMA);
47 pTmp += iStride;
48 ++ i;
49 } while (i < iPicHeight);
50 }
51
H264ExpandPictureChromaAnchor_c(uint8_t * pDst,int32_t iStride,int32_t iPicWidth,int32_t iPicHeight)52 void H264ExpandPictureChromaAnchor_c (uint8_t* pDst, int32_t iStride, int32_t iPicWidth, int32_t iPicHeight) {
53 uint8_t* pTmp = pDst;
54 uint8_t* pDstLastLine = pTmp + (iPicHeight - 1) * iStride;
55 uint8_t pTL = pTmp[0];
56 uint8_t pTR = pTmp[iPicWidth - 1];
57 uint8_t pBL = pDstLastLine[0];
58 uint8_t pBR = pDstLastLine[iPicWidth - 1];
59 int32_t i = 0;
60
61 do {
62 const int32_t kStrides = (1 + i) * iStride;
63 uint8_t* pTop = pTmp - kStrides;
64 uint8_t* pBottom = pDstLastLine + kStrides;
65
66 // pad pTop and pBottom
67 memcpy (pTop, pTmp, iPicWidth);
68 memcpy (pBottom, pDstLastLine, iPicWidth);
69
70 // pad corners
71 memset (pTop - H264_PADDING_LENGTH_CHROMA, pTL, H264_PADDING_LENGTH_CHROMA); //pTop left
72 memset (pTop + iPicWidth, pTR, H264_PADDING_LENGTH_CHROMA); //pTop right
73 memset (pBottom - H264_PADDING_LENGTH_CHROMA, pBL, H264_PADDING_LENGTH_CHROMA); //pBottom left
74 memset (pBottom + iPicWidth, pBR, H264_PADDING_LENGTH_CHROMA); //pBottom right
75
76 ++ i;
77 } while (i < H264_PADDING_LENGTH_CHROMA);
78
79 // pad left and right
80 i = 0;
81 do {
82 memset (pTmp - H264_PADDING_LENGTH_CHROMA, pTmp[0], H264_PADDING_LENGTH_CHROMA);
83 memset (pTmp + iPicWidth, pTmp[iPicWidth - 1], H264_PADDING_LENGTH_CHROMA);
84
85 pTmp += iStride;
86 ++ i;
87 } while (i < iPicHeight);
88 }
89
CompareBuff(uint8_t * pSrc0,uint8_t * pSrc1,int32_t iStride,int32_t iWidth,int32_t iHeight)90 bool CompareBuff (uint8_t* pSrc0, uint8_t* pSrc1, int32_t iStride, int32_t iWidth, int32_t iHeight) {
91 for (int32_t j = 0; j < iHeight; j++) {
92 for (int32_t i = 0; i < iWidth; i++) {
93 if (pSrc0[i + j * iStride] != pSrc1[i + j * iStride]) {
94 return false;
95 }
96 }
97 }
98 return true;
99 }
100
CompareImage(uint8_t * pSrc0,uint8_t * pSrc1,int32_t iSize)101 bool CompareImage (uint8_t* pSrc0, uint8_t* pSrc1, int32_t iSize) {
102 for (int32_t n = 0; n < iSize; n++) {
103 if (pSrc0[n] != pSrc1[n]) {
104 return false;
105 }
106
107 }
108 return true;
109 }
110
TEST(ExpandPicture,ExpandPictureLuma)111 TEST (ExpandPicture, ExpandPictureLuma) {
112 SExpandPicFunc sExpandPicFunc;
113 int32_t iCpuCores = 1;
114 uint32_t uiCpuFlag = 0;
115 for (int32_t k = 0; k < 2; k++) {
116 if (k == 0) {
117 uiCpuFlag = 0;
118 } else {
119 uiCpuFlag = WelsCPUFeatureDetect (&iCpuCores);
120 }
121 InitExpandPictureFunc (&sExpandPicFunc, uiCpuFlag);
122 for (int32_t iTestIdx = 0; iTestIdx < EXPAND_PIC_TEST_NUM; iTestIdx++) {
123 int32_t iPicWidth = 16 + (rand() % 200) * 16;
124 int32_t iPicHeight = 16 + (rand() % 100) * 16;
125
126 int32_t iStride = iPicWidth + H264_PADDING_LENGTH_LUMA * 2;
127 int32_t iBuffHeight = iPicHeight + H264_PADDING_LENGTH_LUMA * 2;
128 int32_t iBuffSize = iBuffHeight * iStride * sizeof (uint8_t);
129 uint8_t* pAnchorDstBuff = static_cast<uint8_t*> (WelsMallocz (iBuffSize, "pAnchorDstBuff"));
130 ASSERT_TRUE (pAnchorDstBuff != NULL) << "pAnchorDstBuff alloc failed for size:" << iBuffSize;
131 uint8_t* pAnchorDst = pAnchorDstBuff + H264_PADDING_LENGTH_LUMA * iStride + H264_PADDING_LENGTH_LUMA;
132
133 uint8_t* pTestDstBuff = static_cast<uint8_t*> (WelsMallocz (iBuffSize, "pTestDstBuff"));
134 ASSERT_TRUE (pTestDstBuff != NULL) << "pTestDstBuff alloc failed for size:" << iBuffSize;
135 uint8_t* pTestDst = pTestDstBuff + H264_PADDING_LENGTH_LUMA * iStride + H264_PADDING_LENGTH_LUMA;
136
137 // Generate Src
138 for (int32_t j = 0; j < iPicHeight; j++) {
139 for (int32_t i = 0; i < iPicWidth; i++) {
140 pAnchorDst[i + j * iStride] = pTestDst[i + j * iStride] = rand() % 256;
141 }
142 }
143 H264ExpandPictureLumaAnchor_c (pAnchorDst, iStride, iPicWidth, iPicHeight);
144 sExpandPicFunc.pfExpandLumaPicture (pTestDst, iStride, iPicWidth, iPicHeight);
145 EXPECT_EQ (CompareBuff (pAnchorDstBuff, pTestDstBuff, iStride, iPicWidth + H264_PADDING_LENGTH_LUMA * 2,
146 iPicHeight + H264_PADDING_LENGTH_LUMA * 2), true);
147
148 WELS_SAFE_FREE (pAnchorDstBuff, "pAnchorDstBuff");
149 WELS_SAFE_FREE (pTestDstBuff, "pTestDstBuff");
150 }
151 }
152
153 }
154
TEST(ExpandPicture,ExpandPictureChroma)155 TEST (ExpandPicture, ExpandPictureChroma) {
156 SExpandPicFunc sExpandPicFunc;
157 int32_t iCpuCores = 1;
158 uint32_t uiCpuFlag = 0;
159 for (int32_t k = 0; k < 2; k++) {
160 if (k == 0) {
161 uiCpuFlag = 0;
162 } else {
163 uiCpuFlag = WelsCPUFeatureDetect (&iCpuCores);
164 }
165 InitExpandPictureFunc (&sExpandPicFunc, uiCpuFlag);
166
167 for (int32_t iTestIdx = 0; iTestIdx < EXPAND_PIC_TEST_NUM; iTestIdx++) {
168 int32_t iPicWidth = (8 + (rand() % 200) * 8);
169 if (uiCpuFlag & WELS_CPU_SSE2) {
170 iPicWidth = WELS_MAX (iPicWidth, 16);
171 }
172 int32_t iPicHeight = (8 + (rand() % 100) * 8);
173
174 int32_t iStride = (iPicWidth + H264_PADDING_LENGTH_CHROMA * 2 + 8) >> 4 << 4;
175 int32_t iBuffHeight = iPicHeight + H264_PADDING_LENGTH_CHROMA * 2;
176 int32_t iBuffSize = iBuffHeight * iStride * sizeof (uint8_t);
177 uint8_t* pAnchorDstBuff = static_cast<uint8_t*> (WelsMallocz (iBuffSize, "pAnchorDstBuff"));
178 ASSERT_TRUE (pAnchorDstBuff != NULL) << "pAnchorDstBuff alloc failed for size:" << iBuffSize;
179 uint8_t* pAnchorDst = pAnchorDstBuff + H264_PADDING_LENGTH_CHROMA * iStride + H264_PADDING_LENGTH_CHROMA;
180
181 uint8_t* pTestDstBuff = static_cast<uint8_t*> (WelsMallocz (iBuffSize, "pTestDstBuff"));
182 ASSERT_TRUE (pTestDstBuff != NULL) << "pTestDstBuff alloc failed for size:" << iBuffSize;
183 uint8_t* pTestDst = pTestDstBuff + H264_PADDING_LENGTH_CHROMA * iStride + H264_PADDING_LENGTH_CHROMA;
184
185 // Generate Src
186 for (int32_t j = 0; j < iPicHeight; j++) {
187 for (int32_t i = 0; i < iPicWidth; i++) {
188 pAnchorDst[i + j * iStride] = pTestDst[i + j * iStride] = rand() % 256;
189 }
190 }
191 H264ExpandPictureChromaAnchor_c (pAnchorDst, iStride, iPicWidth, iPicHeight);
192 sExpandPicFunc.pfExpandChromaPicture[0] (pTestDst, iStride, iPicWidth, iPicHeight);
193 EXPECT_EQ (CompareBuff (pAnchorDstBuff, pTestDstBuff, iStride, iPicWidth + H264_PADDING_LENGTH_CHROMA * 2,
194 iPicHeight + H264_PADDING_LENGTH_CHROMA * 2), true);
195
196 WELS_SAFE_FREE (pAnchorDstBuff, "pAnchorDstBuff");
197 WELS_SAFE_FREE (pTestDstBuff, "pTestDstBuff");
198 }
199 }
200
201 }
202
TEST(ExpandPicture,ExpandPicForMotion)203 TEST (ExpandPicture, ExpandPicForMotion) {
204 SExpandPicFunc sExpandPicFunc;
205 int32_t iCpuCores = 1;
206 uint32_t uiCpuFlag = 0;
207 for (int32_t k = 0; k < 2; k++) {
208 if (k == 0) {
209 uiCpuFlag = 0;
210 } else {
211 uiCpuFlag = WelsCPUFeatureDetect (&iCpuCores);
212 }
213 InitExpandPictureFunc (&sExpandPicFunc, uiCpuFlag);
214 uint8_t* pPicAnchorBuffer = NULL;
215 uint8_t* pPicTestBuffer = NULL;
216 uint8_t* pPicAnchor[3] = {NULL, NULL, NULL};
217 uint8_t* pPicTest[3] = {NULL, NULL, NULL};
218 int32_t iStride[3];
219 for (int32_t iTestIdx = 0; iTestIdx < EXPAND_PIC_TEST_NUM; iTestIdx++) {
220 int32_t iPicWidth = (16 + (rand() % 200) * 16);
221 int32_t iPicHeight = (16 + (rand() % 100) * 16);
222 if (uiCpuFlag & WELS_CPU_SSE2) {
223 iPicWidth = WELS_ALIGN (iPicWidth, 32);
224 }
225 iStride[0] = WELS_ALIGN (iPicWidth,
226 MB_WIDTH_LUMA) + (PADDING_LENGTH << 1); // with width of horizon
227 int32_t iPicHeightExt = WELS_ALIGN (iPicHeight,
228 MB_HEIGHT_LUMA) + (PADDING_LENGTH << 1); // with height of vertical
229 iStride[1] = iStride[0] >> 1;
230 int32_t iPicChromaHeightExt = iPicHeightExt >> 1;
231 iStride[2] = iStride[1];
232 int32_t iLumaSize = iStride[0] * iPicHeightExt;
233 int32_t iChromaSize = iStride[1] * iPicChromaHeightExt;
234
235 pPicAnchorBuffer = static_cast<uint8_t*> (WelsMallocz (iLumaSize + (iChromaSize << 1), "pPicAnchor"));
236 ASSERT_TRUE (pPicAnchorBuffer != NULL) << "pPicAnchorBuffer alloc failed for size:" << (iLumaSize + (iChromaSize << 1));
237 pPicAnchor[0] = pPicAnchorBuffer + (1 + iStride[0]) * PADDING_LENGTH;
238 pPicAnchor[1] = pPicAnchorBuffer + iLumaSize + (((1 + iStride[1]) * PADDING_LENGTH) >> 1);
239 pPicAnchor[2] = pPicAnchorBuffer + iLumaSize + iChromaSize + (((1 + iStride[2]) * PADDING_LENGTH) >> 1);
240
241 pPicTestBuffer = static_cast<uint8_t*> (WelsMallocz (iLumaSize + (iChromaSize << 1), "pPicTest"));
242 ASSERT_TRUE (pPicTestBuffer != NULL) << "pPicTestBuffer alloc failed for size:" << (iLumaSize + (iChromaSize << 1));
243 pPicTest[0] = pPicTestBuffer + (1 + iStride[0]) * PADDING_LENGTH;
244 pPicTest[1] = pPicTestBuffer + iLumaSize + (((1 + iStride[1]) * PADDING_LENGTH) >> 1);
245 pPicTest[2] = pPicTestBuffer + iLumaSize + iChromaSize + (((1 + iStride[2]) * PADDING_LENGTH) >> 1);
246
247
248 // Generate Src
249 for (int32_t j = 0; j < iPicHeight; j++) {
250 for (int32_t i = 0; i < iPicWidth; i++) {
251 pPicAnchor[0][i + j * iStride[0]] = pPicTest[0][i + j * iStride[0]] = rand() % 256;
252 }
253 }
254 for (int32_t j = 0; j < iPicHeight / 2; j++) {
255 for (int32_t i = 0; i < iPicWidth / 2; i++) {
256 pPicAnchor[1][i + j * iStride[1]] = pPicTest[1][i + j * iStride[1]] = rand() % 256;
257 pPicAnchor[2][i + j * iStride[2]] = pPicTest[2][i + j * iStride[2]] = rand() % 256;
258 }
259 }
260 H264ExpandPictureLumaAnchor_c (pPicAnchor[0], iStride[0], iPicWidth, iPicHeight);
261 H264ExpandPictureChromaAnchor_c (pPicAnchor[1], iStride[1], iPicWidth / 2, iPicHeight / 2);
262 H264ExpandPictureChromaAnchor_c (pPicAnchor[2], iStride[2], iPicWidth / 2, iPicHeight / 2);
263 ExpandReferencingPicture (pPicTest, iPicWidth, iPicHeight, iStride,
264 sExpandPicFunc.pfExpandLumaPicture, sExpandPicFunc.pfExpandChromaPicture);
265 EXPECT_EQ (CompareImage (pPicAnchorBuffer, pPicTestBuffer, (iLumaSize + (iChromaSize << 1))), true);
266
267
268 WELS_SAFE_FREE (pPicAnchorBuffer, "pPicAnchor");
269 WELS_SAFE_FREE (pPicTestBuffer, "pPicTest");
270
271 }
272 }
273 }
274
275