6#include <winpr/crypto.h>
9#include <freerdp/freerdp.h>
10#include <freerdp/settings.h>
11#include <freerdp/codec/color.h>
12#include <freerdp/codec/yuv.h>
21#define TEST_TAG "TestFreeRDPCodecYuv"
22#define TEST_WIDTH 320u
23#define TEST_HEIGHT 200u
28#define TEST_STRIDE (TEST_WIDTH + 32u - TEST_WIDTH % 16u)
29#define TEST_PHEIGHT (TEST_HEIGHT + 32u - TEST_HEIGHT % 16u)
30#define TEST_PLANE_SIZE (1ull * TEST_STRIDE * TEST_PHEIGHT)
32static void free_planes(BYTE* planes[TEST_PLANES])
34 for (
size_t x = 0; x < TEST_PLANES; x++)
41static BOOL alloc_planes(BYTE* planes[TEST_PLANES])
43 for (
size_t x = 0; x < TEST_PLANES; x++)
45 planes[x] = calloc(1, TEST_PLANE_SIZE);
52static BOOL encode(YUV_CONTEXT* context, BYTE version,
const BYTE* src, UINT32 srcStep,
55 const UINT32 stride[3] = { TEST_STRIDE, (TEST_STRIDE + 1) / 2, (TEST_STRIDE + 1) / 2 };
56 BYTE* luma[3] = { planes[0], planes[1], planes[2] };
57 BYTE* chroma[3] = { planes[3], planes[4], planes[5] };
60 return yuv420_context_encode(context, src, srcStep, PIXEL_FORMAT_BGRX32, stride, luma, rect,
62 return yuv444_context_encode(context, version, src, srcStep, PIXEL_FORMAT_BGRX32, stride, luma,
66static BOOL compare_rect(YUV_CONTEXT* threaded, YUV_CONTEXT* single, BYTE version,
const BYTE* src,
70 BYTE* planesA[TEST_PLANES] = WINPR_C_ARRAY_INIT;
71 BYTE* planesB[TEST_PLANES] = WINPR_C_ARRAY_INIT;
73 if (!alloc_planes(planesA) || !alloc_planes(planesB))
76 if (!encode(threaded, version, src, srcStep, planesA, rect) ||
77 !encode(single, version, src, srcStep, planesB, rect))
80 for (
size_t x = 0; x < TEST_PLANES; x++)
82 if (memcmp(planesA[x], planesB[x], TEST_PLANE_SIZE) != 0)
85 "[%s] version %d: plane %" PRIuz
" differs for rect [%" PRIu16
",%" PRIu16
86 "-%" PRIu16
",%" PRIu16
"]\n",
87 TEST_TAG, version, x, rect->left, rect->top, rect->right, rect->bottom);
98int TestFreeRDPCodecYuv(WINPR_ATTR_UNUSED
int argc, WINPR_ATTR_UNUSED
char* argv[])
101 const UINT32 srcStep = TEST_WIDTH * 4u;
102 BYTE* src = calloc(TEST_HEIGHT, srcStep);
103 YUV_CONTEXT* threaded = yuv_context_new(TRUE, 0);
104 YUV_CONTEXT* single = yuv_context_new(TRUE, THREADING_FLAGS_DISABLE_THREADS);
107 const UINT16 tops[] = { 0, 2, 16, 34 };
108 const UINT16 heights[] = { 1, 2, 3, 7, 8, 9, 15, 16, 17, 23, 24, 25, 31, 32, 33, 40, 100, 198 };
109 const UINT16 lefts[] = { 0, 16 };
110 const UINT16 rights[] = { TEST_WIDTH, TEST_WIDTH - 16 };
113 if (!src || !threaded || !single)
115 if (winpr_RAND_pseudo(src, 1ull * TEST_HEIGHT * srcStep) < 0)
117 if (!yuv_context_reset(threaded, TEST_WIDTH, TEST_HEIGHT) ||
118 !yuv_context_reset(single, TEST_WIDTH, TEST_HEIGHT))
122 for (BYTE version = 0; version < 3; version++)
124 for (
size_t t = 0; t < ARRAYSIZE(tops); t++)
126 for (
size_t h = 0; h < ARRAYSIZE(heights); h++)
128 for (
size_t s = 0; s < ARRAYSIZE(lefts); s++)
131 rect.left = lefts[s];
132 rect.right = rights[s];
134 rect.bottom = (UINT16)(tops[t] + heights[h]);
135 if (rect.bottom > TEST_HEIGHT)
138 if (!compare_rect(threaded, single, version, src, srcStep, &rect))
149 (void)fprintf(stderr,
"[%s] only %" PRIuz
" regions tested\n", TEST_TAG, tested);
154 yuv_context_free(threaded);
155 yuv_context_free(single);