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 #include <zephyr/drivers/video-controls.h>
10
11 const struct device *rx_dev = DEVICE_DT_GET(DT_NODELABEL(test_video_emul_rx));
12 const struct device *imager_dev = DEVICE_DT_GET(DT_NODELABEL(test_video_emul_imager));
13
ZTEST(video_common,test_video_device)14 ZTEST(video_common, test_video_device)
15 {
16 zexpect_true(device_is_ready(rx_dev));
17 zexpect_true(device_is_ready(imager_dev));
18
19 zexpect_ok(video_stream_start(imager_dev));
20 zexpect_ok(video_stream_stop(imager_dev));
21
22 zexpect_ok(video_stream_start(rx_dev));
23 zexpect_ok(video_stream_stop(rx_dev));
24 }
25
ZTEST(video_common,test_video_format)26 ZTEST(video_common, test_video_format)
27 {
28 struct video_caps caps = {0};
29 struct video_format fmt = {0};
30
31 zexpect_ok(video_get_caps(imager_dev, VIDEO_EP_OUT, &caps));
32
33 /* Test all the formats listed in the caps, the min and max values */
34 for (size_t i = 0; caps.format_caps[i].pixelformat != 0; i++) {
35 fmt.pixelformat = caps.format_caps[i].pixelformat;
36
37 fmt.height = caps.format_caps[i].height_min;
38 fmt.width = caps.format_caps[i].width_min;
39 zexpect_ok(video_set_format(imager_dev, VIDEO_EP_OUT, &fmt));
40 zexpect_ok(video_get_format(imager_dev, VIDEO_EP_OUT, &fmt));
41 zexpect_equal(fmt.pixelformat, caps.format_caps[i].pixelformat);
42 zexpect_equal(fmt.width, caps.format_caps[i].width_min);
43 zexpect_equal(fmt.height, caps.format_caps[i].height_min);
44
45 fmt.height = caps.format_caps[i].height_max;
46 fmt.width = caps.format_caps[i].width_min;
47 zexpect_ok(video_set_format(imager_dev, VIDEO_EP_OUT, &fmt));
48 zexpect_ok(video_get_format(imager_dev, VIDEO_EP_OUT, &fmt));
49 zexpect_equal(fmt.pixelformat, caps.format_caps[i].pixelformat);
50 zexpect_equal(fmt.width, caps.format_caps[i].width_max);
51 zexpect_equal(fmt.height, caps.format_caps[i].height_min);
52
53 fmt.height = caps.format_caps[i].height_min;
54 fmt.width = caps.format_caps[i].width_max;
55 zexpect_ok(video_set_format(imager_dev, VIDEO_EP_OUT, &fmt));
56 zexpect_ok(video_get_format(imager_dev, VIDEO_EP_OUT, &fmt));
57 zexpect_equal(fmt.pixelformat, caps.format_caps[i].pixelformat);
58 zexpect_equal(fmt.width, caps.format_caps[i].width_min);
59 zexpect_equal(fmt.height, caps.format_caps[i].height_max);
60
61 fmt.height = caps.format_caps[i].height_max;
62 fmt.width = caps.format_caps[i].width_max;
63 zexpect_ok(video_set_format(imager_dev, VIDEO_EP_OUT, &fmt));
64 zexpect_ok(video_get_format(imager_dev, VIDEO_EP_OUT, &fmt));
65 zexpect_equal(fmt.pixelformat, caps.format_caps[i].pixelformat);
66 zexpect_equal(fmt.width, caps.format_caps[i].width_max);
67 zexpect_equal(fmt.height, caps.format_caps[i].height_max);
68 }
69
70 fmt.pixelformat = 0x00000000;
71 zexpect_not_ok(video_set_format(imager_dev, VIDEO_EP_OUT, &fmt));
72 zexpect_ok(video_get_format(imager_dev, VIDEO_EP_OUT, &fmt));
73 zexpect_not_equal(fmt.pixelformat, 0x00000000, "should not store wrong formats");
74 }
75
ZTEST(video_common,test_video_frmival)76 ZTEST(video_common, test_video_frmival)
77 {
78 struct video_format fmt;
79 struct video_frmival_enum fie = {.format = &fmt};
80
81 /* Pick the current format for testing the frame interval enumeration */
82 zexpect_ok(video_get_format(imager_dev, VIDEO_EP_OUT, &fmt));
83
84 /* Do a first enumeration of frame intervals, expected to work */
85 zexpect_ok(video_enum_frmival(imager_dev, VIDEO_EP_OUT, &fie));
86 zexpect_equal(fie.index, 1, "fie's index should increment by one at every iteration");
87
88 /* Test that every value of the frame interval enumerator can be applied */
89 do {
90 struct video_frmival q, a;
91 uint32_t min, max, step;
92
93 zexpect_equal_ptr(fie.format, &fmt, "the format should not be changed");
94 zexpect_true(fie.type == VIDEO_FRMIVAL_TYPE_STEPWISE ||
95 fie.type == VIDEO_FRMIVAL_TYPE_DISCRETE);
96
97 switch (fie.type) {
98 case VIDEO_FRMIVAL_TYPE_STEPWISE:
99 /* Get everthing under the same denominator */
100 q.denominator = fie.stepwise.min.denominator *
101 fie.stepwise.max.denominator *
102 fie.stepwise.step.denominator;
103 min = fie.stepwise.max.denominator * fie.stepwise.step.denominator *
104 fie.stepwise.min.numerator;
105 max = fie.stepwise.min.denominator * fie.stepwise.step.denominator *
106 fie.stepwise.max.numerator;
107 step = fie.stepwise.min.denominator * fie.stepwise.max.denominator *
108 fie.stepwise.step.numerator;
109
110 /* Test every supported frame interval */
111 for (q.numerator = min; q.numerator <= max; q.numerator += step) {
112 zexpect_ok(video_set_frmival(imager_dev, VIDEO_EP_OUT, &q));
113 zexpect_ok(video_get_frmival(imager_dev, VIDEO_EP_OUT, &a));
114 zexpect_equal(video_frmival_nsec(&q), video_frmival_nsec(&a));
115 }
116 break;
117 case VIDEO_FRMIVAL_TYPE_DISCRETE:
118 /* There is just one frame interval to test */
119 zexpect_ok(video_set_frmival(imager_dev, VIDEO_EP_OUT, &fie.discrete));
120 zexpect_ok(video_get_frmival(imager_dev, VIDEO_EP_OUT, &a));
121
122 zexpect_equal(video_frmival_nsec(&fie.discrete), video_frmival_nsec(&a));
123 break;
124 }
125 } while (video_enum_frmival(imager_dev, VIDEO_EP_OUT, &fie) == 0);
126 }
127
ZTEST(video_common,test_video_ctrl)128 ZTEST(video_common, test_video_ctrl)
129 {
130 int value;
131
132 /* Exposure control, expected to be supported by all imagers */
133 zexpect_ok(video_set_ctrl(imager_dev, VIDEO_CID_EXPOSURE, (void *)30));
134 zexpect_ok(video_get_ctrl(imager_dev, VIDEO_CID_EXPOSURE, &value));
135 zexpect_equal(value, 30);
136
137 /* Gain control, expected to be supported by all imagers */
138 zexpect_ok(video_set_ctrl(imager_dev, VIDEO_CID_GAIN, (void *)30));
139 zexpect_ok(video_get_ctrl(imager_dev, VIDEO_CID_GAIN, &value));
140 zexpect_equal(value, 30);
141 }
142
ZTEST(video_common,test_video_vbuf)143 ZTEST(video_common, test_video_vbuf)
144 {
145 struct video_caps caps;
146 struct video_format fmt;
147 struct video_buffer *vbuf = NULL;
148
149 /* Get a list of supported format */
150 zexpect_ok(video_get_caps(rx_dev, VIDEO_EP_OUT, &caps));
151
152 /* Pick set first format, just to use something supported */
153 fmt.pixelformat = caps.format_caps[0].pixelformat;
154 fmt.width = caps.format_caps[0].width_max;
155 fmt.height = caps.format_caps[0].height_max;
156 fmt.pitch = fmt.width * 2;
157 zexpect_ok(video_set_format(rx_dev, VIDEO_EP_OUT, &fmt));
158
159 /* Allocate a buffer, assuming prj.conf gives enough memory for it */
160 vbuf = video_buffer_alloc(fmt.pitch * fmt.height, K_FOREVER);
161 zexpect_not_null(vbuf);
162
163 /* Start the virtual hardware */
164 zexpect_ok(video_stream_start(rx_dev));
165
166 /* Enqueue a first buffer */
167 zexpect_ok(video_enqueue(rx_dev, VIDEO_EP_OUT, vbuf));
168
169 /* Receive the completed buffer */
170 zexpect_ok(video_dequeue(rx_dev, VIDEO_EP_OUT, &vbuf, K_FOREVER));
171 zexpect_not_null(vbuf);
172 zexpect_equal(vbuf->bytesused, vbuf->size);
173
174 /* Enqueue back the same buffer */
175 zexpect_ok(video_enqueue(rx_dev, VIDEO_EP_OUT, vbuf));
176
177 /* Process the remaining buffers */
178 zexpect_ok(video_flush(rx_dev, VIDEO_EP_OUT, false));
179
180 /* Expect the buffer to immediately be available */
181 zexpect_ok(video_dequeue(rx_dev, VIDEO_EP_OUT, &vbuf, K_FOREVER));
182 zexpect_not_null(vbuf);
183 zexpect_equal(vbuf->bytesused, vbuf->size);
184
185 /* Nothing left in the queue, possible to stop */
186 zexpect_ok(video_stream_stop(rx_dev));
187 }
188
189 ZTEST_SUITE(video_emul, NULL, NULL, NULL, NULL, NULL);
190