1 /*
2  * Copyright (c) 2024 tinyVision.ai Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <zephyr/drivers/video.h>
9 
10 enum {
11 	RGB565,
12 	YUYV_A,
13 	YUYV_B,
14 };
15 
16 static const struct video_format_cap fmts[] = {
17 	[RGB565] = {.pixelformat = VIDEO_PIX_FMT_RGB565,
18 		    .width_min  = 1280, .width_max  = 1280, .width_step  = 50,
19 		    .height_min = 720,  .height_max = 720,  .height_step = 50},
20 	[YUYV_A] = {.pixelformat = VIDEO_PIX_FMT_YUYV,
21 		    .width_min  = 100,  .width_max  = 1000, .width_step  = 50,
22 		    .height_min = 100,  .height_max = 1000, .height_step = 50},
23 	[YUYV_B] = {.pixelformat = VIDEO_PIX_FMT_YUYV,
24 		    .width_min  = 1920, .width_max  = 1920, .width_step  = 0,
25 		    .height_min = 1080, .height_max = 1080, .height_step = 0},
26 	{0},
27 };
28 
ZTEST(video_common,test_video_format_caps_index)29 ZTEST(video_common, test_video_format_caps_index)
30 {
31 	struct video_format fmt = {0};
32 	size_t idx;
33 	int ret;
34 
35 	fmt.pixelformat = VIDEO_PIX_FMT_YUYV;
36 
37 	fmt.width = 100;
38 	fmt.height = 100;
39 	fmt.pitch = 100 * 2;
40 	ret = video_format_caps_index(fmts, &fmt, &idx);
41 	zassert_ok(ret, "expecting minimum value to match");
42 	zassert_equal(idx, YUYV_A);
43 
44 	fmt.width = 1000;
45 	fmt.height = 1000;
46 	fmt.pitch = 1000 * 2;
47 	ret = video_format_caps_index(fmts, &fmt, &idx);
48 	zassert_ok(ret, "expecting maximum value to match");
49 	zassert_equal(idx, YUYV_A);
50 
51 	fmt.width = 1920;
52 	fmt.height = 1080;
53 	fmt.pitch = 1920 * 2;
54 	ret = video_format_caps_index(fmts, &fmt, &idx);
55 	zassert_ok(ret, "expecting exact match to work");
56 	zassert_equal(idx, YUYV_B);
57 
58 	fmt.width = 1001;
59 	fmt.height = 1000;
60 	fmt.pitch = 1001 * 2;
61 	ret = video_format_caps_index(fmts, &fmt, &idx);
62 	zassert_not_ok(ret, "expecting 1 above maximum width to mismatch");
63 
64 	fmt.width = 1000;
65 	fmt.height = 1001;
66 	fmt.pitch = 1000 * 2;
67 	ret = video_format_caps_index(fmts, &fmt, &idx);
68 	zassert_not_ok(ret, "expecting 1 above maximum height to mismatch");
69 
70 	fmt.width = 1280;
71 	fmt.height = 720;
72 	fmt.pitch = 1280 * 2;
73 	ret = video_format_caps_index(fmts, &fmt, &idx);
74 	zassert_not_ok(ret);
75 	zassert_not_ok(ret, "expecting wrong format to mismatch");
76 
77 	fmt.pixelformat = VIDEO_PIX_FMT_RGB565;
78 
79 	fmt.width = 1000;
80 	fmt.height = 1000;
81 	fmt.pitch = 1000 * 2;
82 	ret = video_format_caps_index(fmts, &fmt, &idx);
83 	zassert_not_ok(ret, "expecting wrong format to mismatch");
84 
85 	fmt.width = 1280;
86 	fmt.height = 720;
87 	fmt.pitch = 1280 * 2;
88 	ret = video_format_caps_index(fmts, &fmt, &idx);
89 	zassert_ok(ret, "expecting exact match to work");
90 	zassert_equal(idx, RGB565);
91 }
92 
ZTEST(video_common,test_video_frmival_nsec)93 ZTEST(video_common, test_video_frmival_nsec)
94 {
95 	zassert_equal(
96 		video_frmival_nsec(&(struct video_frmival){.numerator = 1, .denominator = 15}),
97 		66666666);
98 
99 	zassert_equal(
100 		video_frmival_nsec(&(struct video_frmival){.numerator = 1, .denominator = 30}),
101 		33333333);
102 
103 	zassert_equal(
104 		video_frmival_nsec(&(struct video_frmival){.numerator = 5, .denominator = 1}),
105 		5000000000);
106 
107 	zassert_equal(
108 		video_frmival_nsec(&(struct video_frmival){.numerator = 1, .denominator = 1750000}),
109 		571);
110 }
111 
ZTEST(video_common,test_video_closest_frmival_stepwise)112 ZTEST(video_common, test_video_closest_frmival_stepwise)
113 {
114 	struct video_frmival_stepwise stepwise;
115 	struct video_frmival desired;
116 	struct video_frmival expected;
117 	struct video_frmival match;
118 
119 	stepwise.min.numerator = 1;
120 	stepwise.min.denominator = 30;
121 	stepwise.max.numerator = 30;
122 	stepwise.max.denominator = 30;
123 	stepwise.step.numerator = 1;
124 	stepwise.step.denominator = 30;
125 
126 	desired.numerator = 1;
127 	desired.denominator = 1;
128 	video_closest_frmival_stepwise(&stepwise, &desired, &match);
129 	zassert_equal(video_frmival_nsec(&match), video_frmival_nsec(&desired), "1 / 1");
130 
131 	desired.numerator = 3;
132 	desired.denominator = 30;
133 	video_closest_frmival_stepwise(&stepwise, &desired, &match);
134 	zassert_equal(video_frmival_nsec(&match), video_frmival_nsec(&desired), "3 / 30");
135 
136 	desired.numerator = 7;
137 	desired.denominator = 80;
138 	expected.numerator = 3;
139 	expected.denominator = 30;
140 	video_closest_frmival_stepwise(&stepwise, &desired, &match);
141 	zassert_equal(video_frmival_nsec(&match), video_frmival_nsec(&expected), "7 / 80");
142 
143 	desired.numerator = 1;
144 	desired.denominator = 120;
145 	video_closest_frmival_stepwise(&stepwise, &desired, &match);
146 	zassert_equal(video_frmival_nsec(&match), video_frmival_nsec(&stepwise.min), "1 / 120");
147 
148 	desired.numerator = 100;
149 	desired.denominator = 1;
150 	video_closest_frmival_stepwise(&stepwise, &desired, &match);
151 	zassert_equal(video_frmival_nsec(&match), video_frmival_nsec(&stepwise.max), "100 / 1");
152 }
153 
154 ZTEST_SUITE(video_common, NULL, NULL, NULL, NULL, NULL);
155