History

Add UT for Downsample functions.

zhiliang wang committed 12 years ago

Commit 93af7bf1 parent 81f7b0c3 files · +277 −0Browse files

Showing the changes to test/processing/ProcessUT_DownSample.cpp (1 of 3 files). Show all

Unified · Split

test/processing/ProcessUT_DownSample.cpp+275−0
@@ -0,0 +1,275 @@
1+#include <gtest/gtest.h>
2+#include "cpu.h"
3+#include "cpu_core.h"
4+#include "util.h"
5+#include "macros.h"
6+#include "IWelsVP.h"
7+#include "downsample.h"
8+
9+using namespace nsWelsVP;
10+
11+void DyadicBilinearDownsampler_ref (uint8_t* pDst, const int32_t kiDstStride,
12+ uint8_t* pSrc, const int32_t kiSrcStride,
13+ const int32_t kiSrcWidth, const int32_t kiSrcHeight) {
14+ uint8_t* pDstLine = pDst;
15+ uint8_t* pSrcLine = pSrc;
16+ const int32_t kiSrcStridex2 = kiSrcStride << 1;
17+ const int32_t kiDstWidth = kiSrcWidth >> 1;
18+ const int32_t kiDstHeight = kiSrcHeight >> 1;
19+
20+ for (int32_t j = 0; j < kiDstHeight; j ++) {
21+ for (int32_t i = 0; i < kiDstWidth; i ++) {
22+ const int32_t kiSrcX = i << 1;
23+ const int32_t kiTempRow1 = (pSrcLine[kiSrcX] + pSrcLine[kiSrcX + 1] + 1) >> 1;
24+ const int32_t kiTempRow2 = (pSrcLine[kiSrcX + kiSrcStride] + pSrcLine[kiSrcX + kiSrcStride + 1] + 1) >> 1;
25+
26+ pDstLine[i] = (uint8_t) ((kiTempRow1 + kiTempRow2 + 1) >> 1);
27+ }
28+ pDstLine += kiDstStride;
29+ pSrcLine += kiSrcStridex2;
30+ }
31+}
32+
33+void GeneralBilinearFastDownsampler_ref (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth, const int32_t kiDstHeight,
34+ uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) {
35+ const uint32_t kuiScaleBitWidth = 16, kuiScaleBitHeight = 15;
36+ const uint32_t kuiScaleWidth = (1 << kuiScaleBitWidth), kuiScaleHeight = (1 << kuiScaleBitHeight);
37+ int32_t fScalex = WELS_ROUND ((float)kiSrcWidth / (float)kiDstWidth * kuiScaleWidth);
38+ int32_t fScaley = WELS_ROUND ((float)kiSrcHeight / (float)kiDstHeight * kuiScaleHeight);
39+ uint32_t x;
40+ int32_t iYInverse, iXInverse;
41+
42+ uint8_t* pByDst = pDst;
43+ uint8_t* pByLineDst = pDst;
44+
45+ iYInverse = 1 << (kuiScaleBitHeight - 1);
46+ for (int32_t i = 0; i < kiDstHeight - 1; i++) {
47+ int32_t iYy = iYInverse >> kuiScaleBitHeight;
48+ int32_t fv = iYInverse & (kuiScaleHeight - 1);
49+
50+ uint8_t* pBySrc = pSrc + iYy * kiSrcStride;
51+
52+ pByDst = pByLineDst;
53+ iXInverse = 1 << (kuiScaleBitWidth - 1);
54+ for (int32_t j = 0; j < kiDstWidth - 1; j++) {
55+ int32_t iXx = iXInverse >> kuiScaleBitWidth;
56+ int32_t iFu = iXInverse & (kuiScaleWidth - 1);
57+
58+ uint8_t* pByCurrent = pBySrc + iXx;
59+ uint8_t a, b, c, d;
60+
61+ a = *pByCurrent;
62+ b = * (pByCurrent + 1);
63+ c = * (pByCurrent + kiSrcStride);
64+ d = * (pByCurrent + kiSrcStride + 1);
65+
66+ x = (((uint32_t) (kuiScaleWidth - 1 - iFu)) * (kuiScaleHeight - 1 - fv) >> kuiScaleBitWidth) * a;
67+ x += (((uint32_t) (iFu)) * (kuiScaleHeight - 1 - fv) >> kuiScaleBitWidth) * b;
68+ x += (((uint32_t) (kuiScaleWidth - 1 - iFu)) * (fv) >> kuiScaleBitWidth) * c;
69+ x += (((uint32_t) (iFu)) * (fv) >> kuiScaleBitWidth) * d;
70+ x >>= (kuiScaleBitHeight - 1);
71+ x += 1;
72+ x >>= 1;
73+ //x = (((__int64)(SCALE_BIG - 1 - iFu))*(SCALE_BIG - 1 - fv)*a + ((__int64)iFu)*(SCALE_BIG - 1 -fv)*b + ((__int64)(SCALE_BIG - 1 -iFu))*fv*c +
74+ // ((__int64)iFu)*fv*d + (1 << (2*SCALE_BIT_BIG-1)) ) >> (2*SCALE_BIT_BIG);
75+ x = WELS_CLAMP (x, 0, 255);
76+ *pByDst++ = (uint8_t)x;
77+
78+ iXInverse += fScalex;
79+ }
80+ *pByDst = * (pBySrc + (iXInverse >> kuiScaleBitWidth));
81+ pByLineDst += kiDstStride;
82+ iYInverse += fScaley;
83+ }
84+
85+ // last row special
86+ {
87+ int32_t iYy = iYInverse >> kuiScaleBitHeight;
88+ uint8_t* pBySrc = pSrc + iYy * kiSrcStride;
89+
90+ pByDst = pByLineDst;
91+ iXInverse = 1 << (kuiScaleBitWidth - 1);
92+ for (int32_t j = 0; j < kiDstWidth; j++) {
93+ int32_t iXx = iXInverse >> kuiScaleBitWidth;
94+ *pByDst++ = * (pBySrc + iXx);
95+
96+ iXInverse += fScalex;
97+ }
98+ }
99+}
100+
101+void GeneralBilinearAccurateDownsampler_ref (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth, const int32_t kiDstHeight,
102+ uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) {
103+ const int32_t kiScaleBit = 15;
104+ const int32_t kiScale = (1 << kiScaleBit);
105+ int32_t iScalex = WELS_ROUND ((float)kiSrcWidth / (float)kiDstWidth * kiScale);
106+ int32_t iScaley = WELS_ROUND ((float)kiSrcHeight / (float)kiDstHeight * kiScale);
107+ int64_t x;
108+ int32_t iYInverse, iXInverse;
109+
110+ uint8_t* pByDst = pDst;
111+ uint8_t* pByLineDst = pDst;
112+
113+ iYInverse = 1 << (kiScaleBit - 1);
114+ for (int32_t i = 0; i < kiDstHeight - 1; i++) {
115+ int32_t iYy = iYInverse >> kiScaleBit;
116+ int32_t iFv = iYInverse & (kiScale - 1);
117+
118+ uint8_t* pBySrc = pSrc + iYy * kiSrcStride;
119+
120+ pByDst = pByLineDst;
121+ iXInverse = 1 << (kiScaleBit - 1);
122+ for (int32_t j = 0; j < kiDstWidth - 1; j++) {
123+ int32_t iXx = iXInverse >> kiScaleBit;
124+ int32_t iFu = iXInverse & (kiScale - 1);
125+
126+ uint8_t* pByCurrent = pBySrc + iXx;
127+ uint8_t a, b, c, d;
128+
129+ a = *pByCurrent;
130+ b = * (pByCurrent + 1);
131+ c = * (pByCurrent + kiSrcStride);
132+ d = * (pByCurrent + kiSrcStride + 1);
133+
134+ x = (((int64_t) (kiScale - 1 - iFu)) * (kiScale - 1 - iFv) * a + ((int64_t)iFu) * (kiScale - 1 - iFv) * b + ((int64_t) (
135+ kiScale - 1 - iFu)) * iFv * c +
136+ ((int64_t)iFu) * iFv * d + (int64_t) (1 << (2 * kiScaleBit - 1))) >> (2 * kiScaleBit);
137+ x = WELS_CLAMP (x, 0, 255);
138+ *pByDst++ = (uint8_t)x;
139+
140+ iXInverse += iScalex;
141+ }
142+ *pByDst = * (pBySrc + (iXInverse >> kiScaleBit));
143+ pByLineDst += kiDstStride;
144+ iYInverse += iScaley;
145+ }
146+
147+ // last row special
148+ {
149+ int32_t iYy = iYInverse >> kiScaleBit;
150+ uint8_t* pBySrc = pSrc + iYy * kiSrcStride;
151+
152+ pByDst = pByLineDst;
153+ iXInverse = 1 << (kiScaleBit - 1);
154+ for (int32_t j = 0; j < kiDstWidth; j++) {
155+ int32_t iXx = iXInverse >> kiScaleBit;
156+ *pByDst++ = * (pBySrc + iXx);
157+
158+ iXInverse += iScalex;
159+ }
160+ }
161+}
162+
163+#define GENERATE_DyadicBilinearDownsampler_UT(func, ASM, CPUFLAGS) \
164+TEST (DownSampleTest, func) { \
165+ if (ASM) {\
166+ int32_t iCpuCores = 0; \
167+ uint32_t m_uiCpuFeatureFlag = WelsCPUFeatureDetect (&iCpuCores); \
168+ if (0 == (m_uiCpuFeatureFlag & CPUFLAGS)) \
169+ return; \
170+ } \
171+ ENFORCE_STACK_ALIGN_1D (uint8_t, dst_c, 50000, 16); \
172+ ENFORCE_STACK_ALIGN_1D (uint8_t, src_c, 50000, 16); \
173+ int dst_stride_c; \
174+ int src_stride_c; \
175+ int src_width_c; \
176+ int src_height_c; \
177+ ENFORCE_STACK_ALIGN_1D (uint8_t, dst_a, 50000, 16); \
178+ ENFORCE_STACK_ALIGN_1D (uint8_t, src_a, 50000, 16); \
179+ int dst_stride_a; \
180+ int src_stride_a; \
181+ int src_width_a; \
182+ int src_height_a; \
183+ dst_stride_c = dst_stride_a = 560; \
184+ src_stride_c = src_stride_a = 560; \
185+ src_width_c = src_width_a = 512; \
186+ src_height_c = src_height_a = 80; \
187+ for (int j = 0; j < 50000; j++) { \
188+ dst_c[j] = dst_a[j] = rand() % 256; \
189+ src_c[j] = src_a[j] = rand() % 256; \
190+ } \
191+ DyadicBilinearDownsampler_ref (dst_c, dst_stride_c, src_c, src_stride_c, src_width_c, src_height_c); \
192+ func (dst_a, dst_stride_a, src_a, src_stride_a, src_width_a, src_height_a); \
193+ for (int j = 0; j < (src_height_c >> 1); j++) { \
194+ for (int m = 0; m < (src_width_c >> 1); m++) { \
195+ ASSERT_EQ (dst_c[m + j * dst_stride_c], dst_a[m + j * dst_stride_a]); \
196+ } \
197+ } \
198+}
199+
200+#define GENERATE_GeneralBilinearDownsampler_UT(func, ref, ASM, CPUFLAGS) \
201+TEST (DownSampleTest, func) { \
202+ if (ASM) {\
203+ int32_t iCpuCores = 0; \
204+ uint32_t m_uiCpuFeatureFlag = WelsCPUFeatureDetect (&iCpuCores); \
205+ if (0 == (m_uiCpuFeatureFlag & CPUFLAGS)) \
206+ return; \
207+ } \
208+ ENFORCE_STACK_ALIGN_1D (uint8_t, dst_c, 70000, 16); \
209+ ENFORCE_STACK_ALIGN_1D (uint8_t, src_c, 70000, 16); \
210+ unsigned int dst_stride_c; \
211+ unsigned int dst_width_c; \
212+ unsigned int dst_height_c; \
213+ unsigned int src_stride_c; \
214+ unsigned int src_width_c; \
215+ unsigned int src_height_c; \
216+ ENFORCE_STACK_ALIGN_1D (uint8_t, dst_a, 70000, 16); \
217+ ENFORCE_STACK_ALIGN_1D (uint8_t, src_a, 70000, 16); \
218+ unsigned int dst_stride_a; \
219+ unsigned int dst_width_a; \
220+ unsigned int dst_height_a; \
221+ unsigned int src_stride_a; \
222+ unsigned int src_width_a; \
223+ unsigned int src_height_a; \
224+ dst_stride_c = dst_stride_a = 320; \
225+ src_stride_c = src_stride_a = 320; \
226+ src_width_c = src_width_a = 320; \
227+ src_height_c = src_height_a = 180; \
228+ dst_width_c = dst_width_a = 300; \
229+ dst_height_c = dst_height_a = 160; \
230+ for (int j = 0; j < 70000; j++) { \
231+ dst_c[j] = dst_a[j] = rand() % 256; \
232+ src_c[j] = src_a[j] = rand() % 256; \
233+ } \
234+ ref (dst_c, dst_stride_c, dst_width_c, dst_height_c, src_c, src_stride_c, src_width_c, src_height_c); \
235+ func (dst_a, dst_stride_a, dst_width_a, dst_height_a, src_a, src_stride_a, src_width_a, src_height_a); \
236+ for (int j = 0; j < dst_height_c; j++) { \
237+ for (int m = 0; m < dst_width_c ; m++) { \
238+ ASSERT_EQ (dst_c[m + j * dst_stride_c], dst_a[m + j * dst_stride_a]); \
239+ } \
240+ } \
241+}
242+
243+
244+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsampler_c, 0, 0)
245+GENERATE_GeneralBilinearDownsampler_UT (GeneralBilinearFastDownsampler_c, GeneralBilinearFastDownsampler_ref, 0, 0)
246+GENERATE_GeneralBilinearDownsampler_UT (GeneralBilinearAccurateDownsampler_c, GeneralBilinearAccurateDownsampler_ref, 0, 0)
247+
248+#if defined(X86_ASM)
249+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_sse, 1, WELS_CPU_SSE)
250+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx16_sse, 1, WELS_CPU_SSE)
251+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx8_sse, 1, WELS_CPU_SSE)
252+
253+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_ssse3, 1, WELS_CPU_SSSE3)
254+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx16_ssse3, 1, WELS_CPU_SSSE3)
255+
256+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_sse4, 1, WELS_CPU_SSE41)
257+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx16_sse4, 1, WELS_CPU_SSE41)
258+
259+GENERATE_GeneralBilinearDownsampler_UT (GeneralBilinearFastDownsamplerWrap_sse2, GeneralBilinearFastDownsampler_ref, 1, WELS_CPU_SSE2)
260+GENERATE_GeneralBilinearDownsampler_UT (GeneralBilinearAccurateDownsamplerWrap_sse2, GeneralBilinearAccurateDownsampler_ref, 1, WELS_CPU_SSE2)
261+#endif
262+
263+#if defined(HAVE_NEON)
264+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_neon, 1, WELS_CPU_NEON)
265+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsampler_neon, 1, WELS_CPU_NEON)
266+
267+GENERATE_GeneralBilinearDownsampler_UT (GeneralBilinearAccurateDownsamplerWrap_neon, GeneralBilinearAccurateDownsampler_ref, 1, WELS_CPU_NEON)
268+#endif
269+
270+#if defined(HAVE_NEON_AARCH64)
271+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_AArch64_neon, 1, WELS_CPU_NEON)
272+GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsampler_AArch64_neon, 1, WELS_CPU_NEON)
273+
274+GENERATE_GeneralBilinearDownsampler_UT (GeneralBilinearAccurateDownsamplerWrap_AArch64_neon, GeneralBilinearAccurateDownsampler_ref, 1, WELS_CPU_NEON)
275+#endif

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