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