4#include <freerdp/freerdp.h>
5#include <freerdp/codec/color.h>
6#include <freerdp/codec/av1.h>
8static void* allocRGB(uint32_t format, uint32_t width, uint32_t height, uint32_t* pstride)
10 const size_t bpp = FreeRDPGetBytesPerPixel(format);
11 const size_t stride = bpp * width + 32;
12 WINPR_ASSERT(pstride);
13 *pstride = WINPR_ASSERTING_INT_CAST(uint32_t, stride);
15 uint8_t* rgb = calloc(stride, height);
19 for (
size_t x = 0; x < height; x++)
21 if (winpr_RAND(&rgb[x * stride], width * bpp) < 0)
30static BOOL testEncodeDecode(uint32_t format, uint32_t width, uint32_t height)
36 FREERDP_AV1_CONTEXT* enc = freerdp_av1_context_new(TRUE);
37 FREERDP_AV1_CONTEXT* dec = freerdp_av1_context_new(FALSE);
41 if (!freerdp_av1_context_reset(enc, width, height))
43 if (!freerdp_av1_context_reset(dec, width, height))
48 src = allocRGB(format, width, height, &stride);
49 out = allocRGB(format, width, height, &ostride);
50 if (!src || !out || (stride < width) || (stride != ostride))
53 const RECTANGLE_16 rect = { .left = 0, .top = 0, .right = width, .bottom = height };
54 uint8_t* dst =
nullptr;
56 if (freerdp_av1_compress(enc, src, format, stride, width, height, &rect, &dst, &dstsize,
59 if ((dstsize == 0) || !dst)
65 rc = freerdp_av1_decompress(dec, dst, dstsize, out, format, stride, width, height, &rect, 1) >=
69 freerdp_av1_context_free(enc);
70 freerdp_av1_context_free(dec);
71 free_h264_metablock(&meta);
81static BOOL testYUV444Colours(uint32_t width, uint32_t height)
83 const uint32_t format = PIXEL_FORMAT_BGRX32;
84 const uint32_t bpp = FreeRDPGetBytesPerPixel(format);
85 const uint32_t stride = width * bpp;
87 uint8_t* src = calloc(stride, height);
88 uint8_t* out = calloc(stride, height);
90 FREERDP_AV1_CONTEXT* enc = freerdp_av1_context_new(TRUE);
91 FREERDP_AV1_CONTEXT* dec = freerdp_av1_context_new(FALSE);
92 if (!src || !out || !enc || !dec)
95 if (!freerdp_av1_context_reset(enc, width, height) ||
96 !freerdp_av1_context_reset(dec, width, height))
98 if (!freerdp_av1_context_set_option(enc, FREERDP_AV1_CONTEXT_OPTION_PROFILE, 1) ||
99 !freerdp_av1_context_set_option(enc, FREERDP_AV1_CONTEXT_OPTION_RATECONTROL,
101 !freerdp_av1_context_set_option(enc, FREERDP_AV1_CONTEXT_OPTION_BITRATE, 100000))
104 for (uint32_t y = 0; y < height; y++)
106 for (uint32_t x = 0; x < width; x++)
108 const BOOL first = ((x % 2) == 0) && ((y % 2) == 0);
109 const uint32_t color = first ? FreeRDPGetColor(format, 0xA0, 0x60, 0x60, 0xFF)
110 : FreeRDPGetColor(format, 0x60, 0x60, 0xA0, 0xFF);
111 if (!FreeRDPWriteColor(&src[y * stride + x * bpp], format, color))
116 const RECTANGLE_16 rect = { .left = 0, .top = 0, .right = width, .bottom = height };
117 uint8_t* dst =
nullptr;
118 uint32_t dstsize = 0;
119 if (freerdp_av1_compress(enc, src, format, stride, width, height, &rect, &dst, &dstsize,
122 if (freerdp_av1_decompress(dec, dst, dstsize, out, format, stride, width, height, &rect, 1) < 0)
126 for (uint32_t y = 0; y < height; y++)
128 for (uint32_t x = 0; x < width; x++)
136 FreeRDPSplitColor(FreeRDPReadColor(&src[y * stride + x * bpp], format), format, &r1,
137 &g1, &b1,
nullptr,
nullptr);
138 FreeRDPSplitColor(FreeRDPReadColor(&out[y * stride + x * bpp], format), format, &r2,
139 &g2, &b2,
nullptr,
nullptr);
140 maxDiff = MAX(maxDiff, abs(r1 - r2));
141 maxDiff = MAX(maxDiff, abs(g1 - g2));
142 maxDiff = MAX(maxDiff, abs(b1 - b2));
146 (void)fprintf(stderr,
"[%s] %" PRIu32
"x%" PRIu32
": maximum colour difference %d\n", __func__,
147 width, height, maxDiff);
151 freerdp_av1_context_free(enc);
152 freerdp_av1_context_free(dec);
153 free_h264_metablock(&meta);
159int TestFreeRDPCodecAV1(
int argc,
char* argv[])
164#if !defined(WITH_LIBAOM)
165 (void)fprintf(stderr,
"[%s] skipping, no AV1 encoder support compiled in\n", __func__);
168 const UINT32 width = 124;
169 const UINT32 height = 54;
170 const UINT32 formats[] = { PIXEL_FORMAT_BGRA32, PIXEL_FORMAT_RGB16 };
172 for (
size_t x = 0; x < ARRAYSIZE(formats); x++)
174 if (!testEncodeDecode(formats[x], width, height))
178 if (!testYUV444Colours(64, 64))