FreeRDP
Loading...
Searching...
No Matches
TestFreeRDPCodecAV1.c
1
2#include <stdlib.h>
3
4#include <freerdp/freerdp.h>
5#include <freerdp/codec/color.h>
6#include <freerdp/codec/av1.h>
7
8static void* allocRGB(uint32_t format, uint32_t width, uint32_t height, uint32_t* pstride)
9{
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);
14
15 uint8_t* rgb = calloc(stride, height);
16 if (!rgb)
17 return nullptr;
18
19 for (size_t x = 0; x < height; x++)
20 {
21 if (winpr_RAND(&rgb[x * stride], width * bpp) < 0)
22 {
23 free(rgb);
24 return nullptr;
25 }
26 }
27 return rgb;
28}
29
30static BOOL testEncodeDecode(uint32_t format, uint32_t width, uint32_t height)
31{
32 BOOL rc = FALSE;
33 void* src = nullptr;
34 void* out = nullptr;
35 RDPGFX_H264_METABLOCK meta = WINPR_C_ARRAY_INIT;
36 FREERDP_AV1_CONTEXT* enc = freerdp_av1_context_new(TRUE);
37 FREERDP_AV1_CONTEXT* dec = freerdp_av1_context_new(FALSE);
38 if (!enc || !dec)
39 goto fail;
40
41 if (!freerdp_av1_context_reset(enc, width, height))
42 goto fail;
43 if (!freerdp_av1_context_reset(dec, width, height))
44 goto fail;
45
46 uint32_t stride = 0;
47 uint32_t ostride = 0;
48 src = allocRGB(format, width, height, &stride);
49 out = allocRGB(format, width, height, &ostride);
50 if (!src || !out || (stride < width) || (stride != ostride))
51 goto fail;
52
53 const RECTANGLE_16 rect = { .left = 0, .top = 0, .right = width, .bottom = height };
54 uint8_t* dst = nullptr;
55 uint32_t dstsize = 0;
56 if (freerdp_av1_compress(enc, src, format, stride, width, height, &rect, &dst, &dstsize,
57 &meta) < 0)
58 goto fail;
59 if ((dstsize == 0) || !dst)
60 goto fail;
61
62 /* AV1 is a lossy codec, so this only checks that the bitstream produced by the
63 * encoder (always libaom) round-trips through whichever decoder backend is active
64 * (dav1d or libaom) without error. It does not compare decoded pixels. */
65 rc = freerdp_av1_decompress(dec, dst, dstsize, out, format, stride, width, height, &rect, 1) >=
66 0;
67
68fail:
69 freerdp_av1_context_free(enc);
70 freerdp_av1_context_free(dec);
71 free_h264_metablock(&meta);
72 free(src);
73 free(out);
74 return rc;
75}
76
77int TestFreeRDPCodecAV1(int argc, char* argv[])
78{
79 WINPR_UNUSED(argc);
80 WINPR_UNUSED(argv);
81
82#if !defined(WITH_LIBAOM)
83 (void)fprintf(stderr, "[%s] skipping, no AV1 encoder support compiled in\n", __func__);
84 return 0;
85#else
86 const UINT32 width = 124;
87 const UINT32 height = 54;
88 const UINT32 formats[] = { PIXEL_FORMAT_BGRA32, PIXEL_FORMAT_RGB16 };
89
90 for (size_t x = 0; x < ARRAYSIZE(formats); x++)
91 {
92 if (!testEncodeDecode(formats[x], width, height))
93 return -1;
94 }
95
96 return 0;
97#endif
98}