1 #include "tests.h"
2 #include "libplacebo/utils/libav.h"
3 
main()4 int main()
5 {
6     struct pl_plane_data data[4] = {0};
7     struct pl_bit_encoding bits;
8 
9 #define TEST(pixfmt, reference)                                         \
10     do {                                                                \
11         int planes = pl_plane_data_from_pixfmt(data, &bits, pixfmt);    \
12         REQUIRE(planes == sizeof(reference) / sizeof(*reference));      \
13         REQUIRE(memcmp(data, reference, sizeof(reference)) == 0);       \
14     } while (0)
15 
16     // Planar and semiplanar formats
17     static const struct pl_plane_data yuvp8[] = {
18         {
19             .type = PL_FMT_UNORM,
20             .component_size = {8},
21             .component_map = {0},
22             .pixel_stride = 1,
23         }, {
24             .type = PL_FMT_UNORM,
25             .component_size = {8},
26             .component_map = {1},
27             .pixel_stride = 1,
28         }, {
29             .type = PL_FMT_UNORM,
30             .component_size = {8},
31             .component_map = {2},
32             .pixel_stride = 1,
33         }
34     };
35 
36     TEST(AV_PIX_FMT_YUV420P, yuvp8);
37     TEST(AV_PIX_FMT_YUV422P, yuvp8);
38     TEST(AV_PIX_FMT_YUV444P, yuvp8);
39     TEST(AV_PIX_FMT_YUV410P, yuvp8);
40     TEST(AV_PIX_FMT_YUV411P, yuvp8);
41     TEST(AV_PIX_FMT_YUV440P, yuvp8);
42 
43     static const struct pl_plane_data yuvap8[] = {
44         {
45             .type = PL_FMT_UNORM,
46             .component_size = {8},
47             .component_map = {0},
48             .pixel_stride = 1,
49         }, {
50             .type = PL_FMT_UNORM,
51             .component_size = {8},
52             .component_map = {1},
53             .pixel_stride = 1,
54         }, {
55             .type = PL_FMT_UNORM,
56             .component_size = {8},
57             .component_map = {2},
58             .pixel_stride = 1,
59         }, {
60             .type = PL_FMT_UNORM,
61             .component_size = {8},
62             .component_map = {3},
63             .pixel_stride = 1,
64         }
65     };
66 
67     TEST(AV_PIX_FMT_YUVA420P, yuvap8);
68 
69     static const struct pl_plane_data yuvp16[] = {
70         {
71             .type = PL_FMT_UNORM,
72             .component_size = {16},
73             .component_map = {0},
74             .pixel_stride = 2,
75         }, {
76             .type = PL_FMT_UNORM,
77             .component_size = {16},
78             .component_map = {1},
79             .pixel_stride = 2,
80         }, {
81             .type = PL_FMT_UNORM,
82             .component_size = {16},
83             .component_map = {2},
84             .pixel_stride = 2,
85         }
86     };
87 
88     TEST(AV_PIX_FMT_YUV420P10LE, yuvp16);
89     TEST(AV_PIX_FMT_YUV420P16LE, yuvp16);
90 
91     static const struct pl_plane_data nv12[] = {
92         {
93             .type = PL_FMT_UNORM,
94             .component_size = {8},
95             .component_map = {0},
96             .pixel_stride = 1,
97         }, {
98             .type = PL_FMT_UNORM,
99             .component_size = {8, 8},
100             .component_map = {1, 2},
101             .pixel_stride = 2,
102         }
103     };
104 
105     TEST(AV_PIX_FMT_NV12, nv12);
106 
107     static const struct pl_plane_data nv21[] = {
108         {
109             .type = PL_FMT_UNORM,
110             .component_size = {8},
111             .component_map = {0},
112             .pixel_stride = 1,
113         }, {
114             .type = PL_FMT_UNORM,
115             .component_size = {8, 8},
116             .component_map = {2, 1},
117             .pixel_stride = 2,
118         }
119     };
120 
121     TEST(AV_PIX_FMT_NV21, nv21);
122 
123     static const struct pl_plane_data p016[] = {
124         {
125             .type = PL_FMT_UNORM,
126             .component_size = {16},
127             .component_map = {0},
128             .pixel_stride = 2,
129         }, {
130             .type = PL_FMT_UNORM,
131             .component_size = {16, 16},
132             .component_map = {1, 2},
133             .pixel_stride = 4,
134         }
135     };
136 
137     TEST(AV_PIX_FMT_P010LE, p016);
138     TEST(AV_PIX_FMT_P016LE, p016);
139 
140     // Packed formats
141     static const struct pl_plane_data r8[] = {
142         {
143             .type = PL_FMT_UNORM,
144             .component_size = {8},
145             .component_map = {0},
146             .pixel_stride = 1,
147         }
148     };
149 
150     TEST(AV_PIX_FMT_GRAY8, r8);
151 
152     static const struct pl_plane_data rg8[] = {
153         {
154             .type = PL_FMT_UNORM,
155             .component_size = {8, 8},
156             .component_map = {0, 1},
157             .pixel_stride = 2,
158         }
159     };
160 
161     TEST(AV_PIX_FMT_GRAY8A, rg8);
162 
163     static const struct pl_plane_data rgb8[] = {
164         {
165             .type = PL_FMT_UNORM,
166             .component_size = {8, 8, 8},
167             .component_map = {0, 1, 2},
168             .pixel_stride = 3,
169         }
170     };
171 
172     TEST(AV_PIX_FMT_RGB24, rgb8);
173 
174     static const struct pl_plane_data bgr8[] = {
175         {
176             .type = PL_FMT_UNORM,
177             .component_size = {8, 8, 8},
178             .component_map = {2, 1, 0},
179             .pixel_stride = 3,
180         }
181     };
182 
183     TEST(AV_PIX_FMT_BGR24, bgr8);
184 
185     static const struct pl_plane_data rgbx8[] = {
186         {
187             .type = PL_FMT_UNORM,
188             .component_size = {8, 8, 8},
189             .component_map = {0, 1, 2},
190             .pixel_stride = 4,
191         }
192     };
193 
194     TEST(AV_PIX_FMT_RGB0, rgbx8);
195 
196     static const struct pl_plane_data xrgb8[] = {
197         {
198             .type = PL_FMT_UNORM,
199             .component_size = {8, 8, 8},
200             .component_map = {0, 1, 2},
201             .component_pad = {8, 0, 0},
202             .pixel_stride = 4,
203         }
204     };
205 
206     TEST(AV_PIX_FMT_0RGB, xrgb8);
207 
208     static const struct pl_plane_data rgba8[] = {
209         {
210             .type = PL_FMT_UNORM,
211             .component_size = {8, 8, 8, 8},
212             .component_map = {0, 1, 2, 3},
213             .pixel_stride = 4,
214         }
215     };
216 
217     TEST(AV_PIX_FMT_RGBA, rgba8);
218 
219     static const struct pl_plane_data argb8[] = {
220         {
221             .type = PL_FMT_UNORM,
222             .component_size = {8, 8, 8, 8},
223             .component_map = {3, 0, 1, 2},
224             .pixel_stride = 4,
225         }
226     };
227 
228     TEST(AV_PIX_FMT_ARGB, argb8);
229 
230     static const struct pl_plane_data bgra8[] = {
231         {
232             .type = PL_FMT_UNORM,
233             .component_size = {8, 8, 8, 8},
234             .component_map = {2, 1, 0, 3},
235             .pixel_stride = 4,
236         }
237     };
238 
239     TEST(AV_PIX_FMT_BGRA, bgra8);
240 
241     static const struct pl_plane_data abgr8[] = {
242         {
243             .type = PL_FMT_UNORM,
244             .component_size = {8, 8, 8, 8},
245             .component_map = {3, 2, 1, 0},
246             .pixel_stride = 4,
247         }
248     };
249 
250     TEST(AV_PIX_FMT_ABGR, abgr8);
251 
252     static const struct pl_plane_data r16[] = {
253         {
254             .type = PL_FMT_UNORM,
255             .component_size = {16},
256             .component_map = {0},
257             .pixel_stride = 2,
258         }
259     };
260 
261     TEST(AV_PIX_FMT_GRAY16LE, r16);
262 
263     static const struct pl_plane_data rgb16[] = {
264         {
265             .type = PL_FMT_UNORM,
266             .component_size = {16, 16, 16},
267             .component_map = {0, 1, 2},
268             .pixel_stride = 6,
269         }
270     };
271 
272     TEST(AV_PIX_FMT_RGB48LE, rgb16);
273 
274     static const struct pl_plane_data rgb565[] = {
275         {
276             .type = PL_FMT_UNORM,
277             .component_size = {5, 6, 5},
278             .component_map = {2, 1, 0}, // LSB to MSB
279             .pixel_stride = 2,
280         }
281     };
282 
283     TEST(AV_PIX_FMT_RGB565LE, rgb565);
284 
285     // Test pl_frame <- AVFrame bridge
286     struct pl_frame image;
287     AVFrame *frame = av_frame_alloc();
288     frame->format = AV_PIX_FMT_RGBA;
289     pl_frame_from_avframe(&image, frame);
290     REQUIRE(image.num_planes == 1);
291     REQUIRE(image.repr.sys == PL_COLOR_SYSTEM_RGB);
292 
293     // Test inverse mapping
294     struct pl_color_space csp = image.color;
295     pl_color_space_infer(&csp);
296     pl_avframe_set_color(frame, csp);
297     pl_avframe_set_repr(frame, image.repr);
298     pl_avframe_set_profile(frame, image.profile);
299     pl_frame_from_avframe(&image, frame);
300     pl_color_space_infer(&image.color);
301     REQUIRE(pl_color_space_equal(&csp, &image.color));
302     av_frame_free(&frame);
303 
304     // Test enum functions
305     for (enum pl_color_system sys = 0; sys < PL_COLOR_SYSTEM_COUNT; sys++) {
306         enum AVColorSpace spc = pl_system_to_av(sys);
307         enum pl_color_system sys2 = pl_system_from_av(spc);
308         // Exception to the rule, due to different handling in libav*
309         if (sys != PL_COLOR_SYSTEM_BT_2100_HLG)
310             REQUIRE(!sys2 || sys2 == sys);
311     }
312 
313     for (enum pl_color_levels lev = 0; lev < PL_COLOR_LEVELS_COUNT; lev++) {
314         enum AVColorRange range = pl_levels_to_av(lev);
315         enum pl_color_levels lev2 = pl_levels_from_av(range);
316         REQUIRE(lev2 == lev);
317     }
318 
319     for (enum pl_color_primaries prim = 0; prim < PL_COLOR_PRIM_COUNT; prim++) {
320         enum AVColorPrimaries avpri = pl_primaries_to_av(prim);
321         enum pl_color_primaries prim2 = pl_primaries_from_av(avpri);
322         REQUIRE(!prim2 || prim2 == prim);
323     }
324 
325     for (enum pl_color_transfer trc = 0; trc < PL_COLOR_TRC_COUNT; trc++) {
326         enum AVColorTransferCharacteristic avtrc = pl_transfer_to_av(trc);
327         enum pl_color_transfer trc2 = pl_transfer_from_av(avtrc);
328         REQUIRE(!trc2 || trc2 == trc);
329     }
330 
331     for (enum pl_chroma_location loc = 0; loc < PL_CHROMA_COUNT; loc++) {
332         enum AVChromaLocation avloc = pl_chroma_to_av(loc);
333         enum pl_chroma_location loc2 = pl_chroma_from_av(avloc);
334         REQUIRE(loc2 == loc);
335     }
336 }
337