• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     V4L2 API compliance test tool.
3 
4     Copyright (C) 2008, 2010  Hans Verkuil <hverkuil@xs4all.nl>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335  USA
19  */
20 
21 #ifndef _V4L2_COMPLIANCE_H_
22 #define _V4L2_COMPLIANCE_H_
23 
24 #include <map>
25 #include <set>
26 #include <string>
27 #include <cstdint>
28 
29 #include <linux/videodev2.h>
30 #include <linux/v4l2-subdev.h>
31 #include <linux/media.h>
32 
33 #ifndef NO_LIBV4L2
34 #include <libv4l2.h>
35 #endif
36 
37 #include <cv4l-helpers.h>
38 #include <v4l2-info.h>
39 #include <media-info.h>
40 
41 #if !defined(ENODATA) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
42 #define ENODATA ENOTSUP
43 #endif
44 
45 extern bool show_info;
46 extern bool show_colors;
47 extern bool show_warnings;
48 extern bool no_progress;
49 extern bool exit_on_fail;
50 extern bool exit_on_warn;
51 extern bool is_vivid; // We're testing the vivid driver
52 extern bool is_uvcvideo; // We're testing the uvc driver
53 extern int kernel_version;
54 extern int media_fd;
55 extern unsigned warnings;
56 extern bool has_mmu;
57 
58 enum poll_mode {
59 	POLL_MODE_NONE,
60 	POLL_MODE_SELECT,
61 	POLL_MODE_EPOLL,
62 };
63 
64 #define JPEG_ENCODER (1 << 0)
65 #define JPEG_DECODER (1 << 1)
66 #define STATEFUL_ENCODER (1 << 2)
67 #define STATEFUL_DECODER (1 << 3)
68 #define STATELESS_ENCODER (1 << 4)
69 #define STATELESS_DECODER (1 << 5)
70 
71 #define IS_ENCODER(node) ((node)->codec_mask & (JPEG_ENCODER | STATEFUL_ENCODER | STATELESS_ENCODER))
72 #define IS_DECODER(node) ((node)->codec_mask & (JPEG_DECODER | STATEFUL_DECODER | STATELESS_DECODER))
73 
74 #define V4L2_CTRL_CLASS_VIVID		0x00f00000
75 #define VIVID_CID_VIVID_BASE		(V4L2_CTRL_CLASS_VIVID | 0xf000)
76 #define VIVID_CID_DISCONNECT		(VIVID_CID_VIVID_BASE + 65)
77 #define VIVID_CID_DQBUF_ERROR		(VIVID_CID_VIVID_BASE + 66)
78 #define VIVID_CID_QUEUE_SETUP_ERROR	(VIVID_CID_VIVID_BASE + 67)
79 #define VIVID_CID_BUF_PREPARE_ERROR	(VIVID_CID_VIVID_BASE + 68)
80 #define VIVID_CID_START_STR_ERROR	(VIVID_CID_VIVID_BASE + 69)
81 #define VIVID_CID_QUEUE_ERROR		(VIVID_CID_VIVID_BASE + 70)
82 #define VIVID_CID_REQ_VALIDATE_ERROR	(VIVID_CID_VIVID_BASE + 72)
83 
84 #define VIVID_CID_CUSTOM_BASE		(V4L2_CID_USER_BASE | 0xf000)
85 #define VIVID_CID_INTEGER64		(VIVID_CID_CUSTOM_BASE + 3)
86 #define VIVID_CID_STRING		(VIVID_CID_CUSTOM_BASE + 5)
87 #define VIVID_CID_AREA			(VIVID_CID_CUSTOM_BASE + 11)
88 #define VIVID_CID_RO_INTEGER		(VIVID_CID_CUSTOM_BASE + 12)
89 #define VIVID_CID_U32_DYN_ARRAY		(VIVID_CID_CUSTOM_BASE + 13)
90 #define VIVID_CID_U8_PIXEL_ARRAY	(VIVID_CID_CUSTOM_BASE + 14)
91 
92 #define PIXEL_ARRAY_DIV 16
93 
94 struct test_query_ext_ctrl: v4l2_query_ext_ctrl {
95 	__u64 menu_mask;
96 };
97 
98 using qctrl_map = std::map<__u32, test_query_ext_ctrl>;
99 using pixfmt_map = std::map<__u32, __u32>;
100 using frmsizes_set = std::set<__u64>;
101 using frmsizes_count_map = std::map<__u32, unsigned>;
102 
103 struct base_node;
104 
105 #define V4L2_BUF_TYPE_LAST V4L2_BUF_TYPE_META_OUTPUT
106 
107 struct base_node {
108 	bool is_video;
109 	bool is_radio;
110 	bool is_vbi;
111 	bool is_sdr;
112 	bool is_meta;
113 	bool is_touch;
114 	bool is_m2m;
115 	bool is_io_mc;
116 	bool is_planar;
117 	bool is_ro_subdev;
118 	bool can_capture;
119 	bool can_output;
120 	bool can_scale;
121 	const char *device;
122 	struct node *node2;	/* second open filehandle */
123 	bool has_outputs;
124 	bool has_inputs;
125 	bool has_media;
126 	unsigned tuners;
127 	unsigned modulators;
128 	unsigned inputs;
129 	unsigned audio_inputs;
130 	unsigned outputs;
131 	unsigned audio_outputs;
132 	unsigned cur_io_caps;
133 	unsigned std_controls;
134 	unsigned std_compound_controls;
135 	unsigned priv_controls;
136 	unsigned priv_compound_controls;
137 	unsigned codec_mask;
138 	__u32 media_version;
139 	std::string media_bus_info;
140 	media_entity_desc entity;
141 	__u32 function;
142 	media_pad_desc *pads;
143 	media_link_desc *links;
144 	media_v2_topology *topology;
145 	v4l2_subdev_frame_interval_enum subdev_ival;
146 	bool is_passthrough_subdev;
147 	__u8 has_subdev_enum_code;
148 	__u8 has_subdev_enum_fsize;
149 	__u8 has_subdev_enum_fival;
150 	__u8 has_subdev_fmt;
151 	__u8 has_subdev_selection;
152 	__u8 has_subdev_frame_interval;
153 	int frame_interval_pad;
154 	int enum_frame_interval_pad;
155 	__u32 fbuf_caps;
156 	__u32 buf_caps;
157 	const char *bus_info;
158 	pixfmt_map buftype_pixfmts[V4L2_BUF_TYPE_LAST + 1];
159 	frmsizes_set frmsizes;
160 	frmsizes_count_map frmsizes_count;
161 	bool has_frmintervals;
162 	bool has_enc_cap_frame_interval;
163 	__u32 valid_buftypes;
164 	__u32 valid_buftype;
165 	__u32 valid_memorytype;
166 	bool supports_orphaned_bufs;
167 	// support for this was introduced in 5.9
168 	bool might_support_cache_hints;
169 };
170 
171 struct node : public base_node, public cv4l_fd {
nodenode172 	node() : base_node() {}
173 
174 	qctrl_map controls;
175 	pixfmt_map buftype_pixfmts[V4L2_BUF_TYPE_LAST + 1];
176 
inject_errornode177 	bool inject_error(__u32 id)
178 	{
179 		v4l2_control ctrl = {
180 			.id = id,
181 		};
182 
183 		return is_vivid && !s_ctrl(ctrl);
184 	}
185 };
186 
187 class filehandles {
188 public:
filehandles()189 	filehandles() {}
~filehandles()190 	~filehandles()
191 	{
192 		for (int fh : fhs)
193 			close(fh);
194 	}
195 
add(int fd)196 	int add(int fd)
197 	{
198 		if (fd >= 0)
199 			fhs.insert(fd);
200 		return fd;
201 	}
202 
del(int fd)203 	void del(int fd)
204 	{
205 		if (fd >= 0) {
206 			fhs.erase(fd);
207 			close(fd);
208 		}
209 	}
210 
211 private:
212 	std::set<int> fhs;
213 };
214 
215 #ifndef __FILE_NAME__
216 #define __FILE_NAME__ __FILE__
217 #endif
218 
219 #define COLOR_GREEN(s) "\033[32m" s "\033[0m"
220 #define COLOR_RED(s) "\033[1;31m" s "\033[0m"
221 #define COLOR_BOLD(s) "\033[1m" s "\033[0m"
222 
223 #define info(fmt, args...) 					\
224 	do {							\
225 		if (show_info)					\
226 			printf("\t\tinfo: " fmt, ##args);	\
227 	} while (0)
228 
229 #define info_once(fmt, args...)				\
230 	do {						\
231 		static bool show;			\
232 							\
233 		if (!show) {				\
234 			show = true;			\
235 			info(fmt, ##args);		\
236 		}					\
237 	} while (0)
238 
239 #define warn(fmt, args...) 					\
240 	do {							\
241 		warnings++;					\
242 		if (show_warnings)				\
243 			printf("\t\t%s: %s(%d): " fmt,		\
244 			       show_colors ?			\
245 			       COLOR_BOLD("warn") : "warn",	\
246 			       __FILE_NAME__, __LINE__, ##args);	\
247 		if (exit_on_warn)				\
248 			std::exit(EXIT_FAILURE);		\
249 	} while (0)
250 
251 #define warn_once(fmt, args...)				\
252 	do {						\
253 		static bool show;			\
254 							\
255 		if (!show) {				\
256 			show = true;			\
257 			warn(fmt, ##args);		\
258 		}					\
259 	} while (0)
260 
261 #define warn_on_test(test) 				\
262 	do {						\
263 		if (test)				\
264 			warn("%s\n", #test);		\
265 	} while (0)
266 
267 #define warn_once_on_test(test) 			\
268 	do {						\
269 		if (test)				\
270 			warn_once("%s\n", #test);	\
271 	} while (0)
272 
273 #define warn_or_info(is_info, fmt, args...) 		\
274 	do {						\
275 		if (is_info)				\
276 			info(fmt, ##args);		\
277 		else					\
278 			warn(fmt, ##args);		\
279 	} while (0)
280 
281 #define fail(fmt, args...) 						\
282 ({ 									\
283 	printf("\t\t%s: %s(%d): " fmt, show_colors ?			\
284 	       COLOR_RED("fail") : "fail", __FILE_NAME__, __LINE__, ##args);	\
285 	if (exit_on_fail)						\
286 		std::exit(EXIT_FAILURE);				\
287 	1;								\
288 })
289 
290 #define fail_on_test(test) 				\
291 	do {						\
292 	 	if (test)				\
293 			return fail("%s\n", #test);	\
294 	} while (0)
295 
296 #define fail_on_test_val(test, v)				\
297 	do {							\
298 	 	if (test)					\
299 			return fail("%s (got %d)\n", #test, v);	\
300 	} while (0)
301 
check_fract(const struct v4l2_fract * f)302 static inline int check_fract(const struct v4l2_fract *f)
303 {
304 	if (f->numerator && f->denominator)
305 		return 0;
306 	return 1;
307 }
308 
fract2f(const struct v4l2_fract * f)309 static inline double fract2f(const struct v4l2_fract *f)
310 {
311 	return (double)f->numerator / (double)f->denominator;
312 }
313 
314 #define doioctl(n, r, p) v4l_named_ioctl((n)->g_v4l_fd(), #r, r, p)
315 
316 const char *ok(int res);
317 int check_string(const char *s, size_t len);
318 int check_ustring(const __u8 *s, int len);
319 int check_0(const void *p, int len);
320 int restoreFormat(struct node *node);
321 void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_node, media_type type,
322 	      unsigned frame_count, unsigned all_fmt_frame_count, int parent_media_fd = -1);
323 std::string stream_from(const std::string &pixelformat, bool &use_hdr);
324 
325 // Media Controller ioctl tests
326 int testMediaDeviceInfo(struct node *node);
327 int testMediaTopology(struct node *node);
328 int testMediaEnum(struct node *node);
329 int testMediaSetupLink(struct node *node);
330 void walkTopology(struct node &node, struct node &expbuf_node,
331 		  unsigned frame_count, unsigned all_fmt_frame_count);
332 
333 // Debug ioctl tests
334 int testRegister(struct node *node);
335 int testLogStatus(struct node *node);
336 
337 // Input ioctl tests
338 int testTuner(struct node *node);
339 int testTunerFreq(struct node *node);
340 int testTunerHwSeek(struct node *node);
341 int testEnumInputAudio(struct node *node);
342 int testInput(struct node *node);
343 int testInputAudio(struct node *node);
344 
345 // Output ioctl tests
346 int testModulator(struct node *node);
347 int testModulatorFreq(struct node *node);
348 int testEnumOutputAudio(struct node *node);
349 int testOutput(struct node *node);
350 int testOutputAudio(struct node *node);
351 
352 // Control ioctl tests
353 int testQueryExtControls(struct node *node);
354 int testQueryControls(struct node *node);
355 int testSimpleControls(struct node *node);
356 int testExtendedControls(struct node *node);
357 int testEvents(struct node *node);
358 int testVividDisconnect(struct node *node);
359 int testJpegComp(struct node *node);
360 
361 // I/O configuration ioctl tests
362 int testStd(struct node *node);
363 int testTimings(struct node *node);
364 int testTimingsCap(struct node *node);
365 int testEdid(struct node *node);
366 
367 // Format ioctl tests
368 int testEnumFormats(struct node *node);
369 int testParm(struct node *node);
370 int testFBuf(struct node *node);
371 int testGetFormats(struct node *node);
372 int testTryFormats(struct node *node);
373 int testSetFormats(struct node *node);
374 int testSlicedVBICap(struct node *node);
375 int testCropping(struct node *node);
376 int testComposing(struct node *node);
377 int testScaling(struct node *node);
378 
379 // Codec ioctl tests
380 int testEncoder(struct node *node);
381 int testEncIndex(struct node *node);
382 int testDecoder(struct node *node);
383 
384 // SubDev ioctl tests
385 int testSubDevCap(struct node *node);
386 int testSubDevEnum(struct node *node, unsigned which, unsigned pad, unsigned stream);
387 int testSubDevFormat(struct node *node, unsigned which, unsigned pad, unsigned stream);
388 int testSubDevSelection(struct node *node, unsigned which, unsigned pad, unsigned stream);
389 int testSubDevFrameInterval(struct node *node, unsigned which, unsigned pad, unsigned stream);
390 int testSubDevRouting(struct node *node, unsigned which);
391 
392 // Buffer ioctl tests
393 int testReqBufs(struct node *node);
394 int testReadWrite(struct node *node);
395 int testExpBuf(struct node *node);
396 int testBlockingWait(struct node *node);
397 int testCreateBufsMax(struct node *node);
398 int testRemoveBufs(struct node *node);
399 
400 // 32-bit architecture, 32/64-bit time_t tests
401 int testTime32_64(struct node *node);
402 
403 /*
404  * struct node node:
405  * 	the current media node being tested
406  *
407  * struct node node_m2m_cap:
408  * 	the capture device to be used when testing loopback or m2m, for
409  * 	instance, if the node we are testing is m2m, then node == node_m2m_cap,
410  * 	but if we have a topology like output->capture, node will be the output
411  * 	and node_m2m_cap will be the capture device that v4l2-compliance will
412  * 	use to test the loop
413  */
414 int testMmap(struct node *node, struct node *node_m2m_cap, unsigned frame_count,
415 	     enum poll_mode pollmode);
416 int testUserPtr(struct node *node, struct node *node_m2m_cap,
417 		unsigned frame_count, enum poll_mode pollmode);
418 int testDmaBuf(struct node *expbuf_node, struct node *node,
419 	       struct node *node_m2m_cap, unsigned frame_count,
420 	       enum poll_mode pollmode);
421 int testRequests(struct node *node, bool test_streaming);
422 void streamAllFormats(struct node *node, unsigned frame_count);
423 void streamM2MAllFormats(struct node *node, unsigned frame_count);
424 
425 // Color tests
426 int testColorsAllFormats(struct node *node, unsigned component,
427 			 unsigned skip, unsigned perc);
428 
429 #endif
430