1/*
2 * v4l-test: Test environment for Video For Linux Two API
3 *
4 * 20 Apr 2009  0.9  Added string content validation
5 * 18 Apr 2009  0.8  More strict check for strings
6 * 13 Apr 2009  0.7  Also show type in debug output;
7 *                   Add some debug output
8 *  3 Apr 2009  0.6  Test case for NULL parameter reworked
9 * 28 Mar 2009  0.5  Clean up ret and errno variable names and dprintf() output
10 * 18 Mar 2009  0.4  Duplicated test for V4L2_BUF_TYPE_VIDEO_CAPTURE removed
11 *  1 Jan 2009  0.3  Test cases added for index=S32_MAX and S32_MAX+1;
12 *                   Test functions renamed
13 * 22 Dec 2008  0.2  Test case with NULL parameter added
14 * 18 Dec 2008  0.1  First release
15 *
16 * Written by M�rton N�meth <nm127@freemail.hu>
17 * Released under GPL
18 */
19
20#include <stdio.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <fcntl.h>
24#include <unistd.h>
25#include <sys/ioctl.h>
26#include <errno.h>
27#include <string.h>
28
29#include <linux/videodev2.h>
30#include <linux/errno.h>
31
32#include <CUnit/CUnit.h>
33#include <CUnit/Basic.h>
34
35#include "v4l2_test.h"
36#include "dev_video.h"
37#include "video_limits.h"
38#include "v4l2_validator.h"
39
40#include "test_VIDIOC_ENUM_FMT.h"
41
42static void do_enumerate_formats(enum v4l2_buf_type type)
43{
44	int ret_enum, errno_enum;
45	struct v4l2_fmtdesc format;
46	struct v4l2_fmtdesc format2;
47	__u32 i;
48
49	i = 0;
50	do {
51		memset(&format, 0xff, sizeof(format));
52		format.index = i;
53		format.type = type;
54
55		ret_enum = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
56		errno_enum = errno;
57
58		dprintf
59		    ("\t%s:%u: VIDIOC_ENUM_FMT, index=%u, type=%i, ret_enum=%i, errno_enum=%i\n",
60		     __FILE__, __LINE__, i, type, ret_enum, errno_enum);
61		if (ret_enum == 0) {
62			CU_ASSERT_EQUAL(ret_enum, 0);
63			CU_ASSERT_EQUAL(format.index, i);
64			//CU_ASSERT_EQUAL(format.type, ?);
65			//CU_ASSERT_EQUAL(format.flags, ?);
66
67			CU_ASSERT(0 < strlen((char *)format.description));
68			CU_ASSERT(valid_string
69				  ((char *)format.description,
70				   sizeof(format.description)));
71
72			//CU_ASSERT_EQUAL(format.pixelformat, ?);
73			CU_ASSERT_EQUAL(format.reserved[0], 0);
74			CU_ASSERT_EQUAL(format.reserved[1], 0);
75			CU_ASSERT_EQUAL(format.reserved[2], 0);
76			CU_ASSERT_EQUAL(format.reserved[3], 0);
77
78			/* Check if the unused bytes of the description string is also filled
79			 * with zeros. Also check if there is any padding byte between
80			 * any two fields then this padding byte is also filled with zeros.
81			 */
82			memset(&format2, 0, sizeof(format2));
83			format2.index = format.index;
84			format2.type = format.type;
85			format2.flags = format.flags;
86			strncpy((char *)format2.description,
87				(char *)format.description,
88				sizeof(format2.description));
89			format2.pixelformat = format.pixelformat;
90			CU_ASSERT_EQUAL(memcmp
91					(&format, &format2, sizeof(format)), 0);
92
93			dprintf
94			    ("\tformat = {.index=%u, .type=0x%X, .flags=0x%X, "
95			     ".description=\"%s\", .pixelformat=0x%X, "
96			     ".reserved[]={ 0x%X, 0x%X, 0x%X, 0x%X } }\n",
97			     format.index, format.type, format.flags,
98			     format.description, format.pixelformat,
99			     format.reserved[0], format.reserved[1],
100			     format.reserved[2], format.reserved[3]
101			    );
102
103		} else {
104			CU_ASSERT_EQUAL(ret_enum, -1);
105			CU_ASSERT_EQUAL(errno_enum, EINVAL);
106
107			memset(&format2, 0xff, sizeof(format2));
108			format2.index = i;
109			format2.type = type;
110			CU_ASSERT_EQUAL(memcmp
111					(&format, &format2, sizeof(format)), 0);
112
113		}
114		i++;
115	} while (ret_enum == 0);
116
117}
118
119void test_VIDIOC_ENUM_FMT()
120{
121	do_enumerate_formats(V4L2_BUF_TYPE_VIDEO_CAPTURE);
122	do_enumerate_formats(V4L2_BUF_TYPE_VIDEO_OUTPUT);
123	do_enumerate_formats(V4L2_BUF_TYPE_VIDEO_OVERLAY);
124	do_enumerate_formats(V4L2_BUF_TYPE_VBI_CAPTURE);
125	do_enumerate_formats(V4L2_BUF_TYPE_VBI_OUTPUT);
126	do_enumerate_formats(V4L2_BUF_TYPE_SLICED_VBI_CAPTURE);
127	do_enumerate_formats(V4L2_BUF_TYPE_SLICED_VBI_OUTPUT);
128	do_enumerate_formats(V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY);
129	do_enumerate_formats(V4L2_BUF_TYPE_PRIVATE);
130}
131
132void test_VIDIOC_ENUM_FMT_S32_MAX()
133{
134	int ret_enum, errno_enum;
135	struct v4l2_fmtdesc format;
136	struct v4l2_fmtdesc format2;
137
138	/* test invalid index */
139	memset(&format, 0xff, sizeof(format));
140	format.index = (__u32) S32_MAX;
141	format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
142	ret_enum = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
143	errno_enum = errno;
144
145	dprintf
146	    ("\t%s:%u: VIDIOC_ENUM_FMT, index=%u, type=%i, ret_enum=%i, errno_enum=%i\n",
147	     __FILE__, __LINE__, format.index, format.type, ret_enum,
148	     errno_enum);
149
150	CU_ASSERT_EQUAL(ret_enum, -1);
151	CU_ASSERT_EQUAL(errno_enum, EINVAL);
152
153	/* Check whether the original format struct is untouched */
154	memset(&format2, 0xff, sizeof(format2));
155	format2.index = (__u32) S32_MAX;
156	format2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
157	CU_ASSERT_EQUAL(memcmp(&format, &format2, sizeof(format)), 0);
158}
159
160void test_VIDIOC_ENUM_FMT_S32_MAX_1()
161{
162	int ret_enum, errno_enum;
163	struct v4l2_fmtdesc format;
164	struct v4l2_fmtdesc format2;
165
166	/* test invalid index */
167	memset(&format, 0xff, sizeof(format));
168	format.index = ((__u32) S32_MAX) + 1;
169	format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
170	ret_enum = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
171	errno_enum = errno;
172
173	dprintf
174	    ("\t%s:%u: VIDIOC_ENUM_FMT, index=%u, type=%i, ret_enum=%i, errno_enum=%i\n",
175	     __FILE__, __LINE__, format.index, format.type, ret_enum,
176	     errno_enum);
177
178	CU_ASSERT_EQUAL(ret_enum, -1);
179	CU_ASSERT_EQUAL(errno_enum, EINVAL);
180
181	/* Check whether the original format struct is untouched */
182	memset(&format2, 0xff, sizeof(format2));
183	format2.index = ((__u32) S32_MAX) + 1;
184	format2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
185	CU_ASSERT_EQUAL(memcmp(&format, &format2, sizeof(format)), 0);
186}
187
188void test_VIDIOC_ENUM_FMT_U32_MAX()
189{
190	int ret_enum, errno_enum;
191	struct v4l2_fmtdesc format;
192	struct v4l2_fmtdesc format2;
193
194	/* test invalid index */
195	memset(&format, 0xff, sizeof(format));
196	format.index = U32_MAX;
197	format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
198	ret_enum = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
199	errno_enum = errno;
200
201	dprintf
202	    ("\t%s:%u: VIDIOC_ENUM_FMT, index=%u, type=%i, ret_enum=%i, errno_enum=%i\n",
203	     __FILE__, __LINE__, format.index, format.type, ret_enum,
204	     errno_enum);
205
206	CU_ASSERT_EQUAL(ret_enum, -1);
207	CU_ASSERT_EQUAL(errno_enum, EINVAL);
208
209	/* Check whether the original format struct is untouched */
210	memset(&format2, 0xff, sizeof(format2));
211	format2.index = U32_MAX;
212	format2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
213	CU_ASSERT_EQUAL(memcmp(&format, &format2, sizeof(format)), 0);
214}
215
216void test_VIDIOC_ENUM_FMT_invalid_type()
217{
218	int ret_enum, errno_enum;
219	struct v4l2_fmtdesc format;
220	struct v4l2_fmtdesc format2;
221	int i;
222
223	/* In this test case the .index is valid (0) and only the .type
224	 * is invalid. The .type filed is an enum which is stored in an 'int'.
225	 */
226
227	/* test invalid .type=0 */
228	memset(&format, 0xff, sizeof(format));
229	format.index = 0;
230	format.type = 0;
231	ret_enum = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
232	errno_enum = errno;
233
234	dprintf
235	    ("\t%s:%u: VIDIOC_ENUM_FMT, index=%u, type=%i, ret_enum=%i, errno_enum=%i\n",
236	     __FILE__, __LINE__, format.index, format.type, ret_enum,
237	     errno_enum);
238
239	CU_ASSERT_EQUAL(ret_enum, -1);
240	CU_ASSERT_EQUAL(errno_enum, EINVAL);
241
242	/* Check whether the original format struct is untouched */
243	memset(&format2, 0xff, sizeof(format2));
244	format2.index = 0;
245	format2.type = 0;
246	CU_ASSERT_EQUAL(memcmp(&format, &format2, sizeof(format)), 0);
247
248	/* test invalid .type=SINT_MIN */
249	memset(&format, 0xff, sizeof(format));
250	format.index = 0;
251	format.type = SINT_MIN;
252	ret_enum = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
253	errno_enum = errno;
254
255	dprintf
256	    ("\t%s:%u: VIDIOC_ENUM_FMT, index=%u, type=%i, ret_enum=%i, errno_enum=%i\n",
257	     __FILE__, __LINE__, format.index, format.type, ret_enum,
258	     errno_enum);
259
260	CU_ASSERT_EQUAL(ret_enum, -1);
261	CU_ASSERT_EQUAL(errno_enum, EINVAL);
262
263	/* Check whether the original format struct is untouched */
264	memset(&format2, 0xff, sizeof(format2));
265	format2.index = 0;
266	format2.type = SINT_MIN;
267	CU_ASSERT_EQUAL(memcmp(&format, &format2, sizeof(format)), 0);
268
269	/* test invalid .type=-1 */
270	memset(&format, 0xff, sizeof(format));
271	format.index = 0;
272	format.type = -1;
273	ret_enum = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
274	errno_enum = errno;
275
276	dprintf
277	    ("\t%s:%u: VIDIOC_ENUM_FMT, index=%u, type=%i, ret_enum=%i, errno_enum=%i\n",
278	     __FILE__, __LINE__, format.index, format.type, ret_enum,
279	     errno_enum);
280
281	CU_ASSERT_EQUAL(ret_enum, -1);
282	CU_ASSERT_EQUAL(errno_enum, EINVAL);
283
284	/* Check whether the original format struct is untouched */
285	memset(&format2, 0xff, sizeof(format2));
286	format2.index = 0;
287	format2.type = -1;
288	CU_ASSERT_EQUAL(memcmp(&format, &format2, sizeof(format)), 0);
289
290	/* test invalid .type= 8..0x7F */
291	for (i = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY + 1;
292	     i < V4L2_BUF_TYPE_PRIVATE; i++) {
293		memset(&format, 0xff, sizeof(format));
294		format.index = 0;
295		format.type = i;
296		ret_enum = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
297		errno_enum = errno;
298
299		dprintf
300		    ("\t%s:%u: VIDIOC_ENUM_FMT, index=%u, type=%i, ret_enum=%i, errno_enum=%i\n",
301		     __FILE__, __LINE__, format.index, format.type, ret_enum,
302		     errno_enum);
303
304		CU_ASSERT_EQUAL(ret_enum, -1);
305		CU_ASSERT_EQUAL(errno_enum, EINVAL);
306
307		/* Check whether the original format struct is untouched */
308		memset(&format2, 0xff, sizeof(format2));
309		format2.index = 0;
310		format2.type = i;
311		CU_ASSERT_EQUAL(memcmp(&format, &format2, sizeof(format)), 0);
312	}
313
314	/* .type = 0x80..0x7FFF FFFF is the private range */
315
316	/* Assume that 0x7FFF FFFF is invalid in the private range.
317	 * This might be a wrong assumption, but let's have a test case like
318	 * this for now.
319	 */
320	memset(&format, 0xff, sizeof(format));
321	format.index = 0;
322	format.type = SINT_MAX;
323	ret_enum = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
324	errno_enum = errno;
325
326	dprintf
327	    ("\t%s:%u: VIDIOC_ENUM_FMT, index=%u, type=%i, ret_enum=%i, errno_enum=%i\n",
328	     __FILE__, __LINE__, format.index, format.type, ret_enum,
329	     errno_enum);
330
331	CU_ASSERT_EQUAL(ret_enum, -1);
332	CU_ASSERT_EQUAL(errno_enum, EINVAL);
333
334	/* Check whether the original format struct is untouched */
335	memset(&format2, 0xff, sizeof(format2));
336	format2.index = 0;
337	format2.type = SINT_MAX;
338	CU_ASSERT_EQUAL(memcmp(&format, &format2, sizeof(format)), 0);
339}
340
341void test_VIDIOC_ENUM_FMT_NULL()
342{
343	int ret_capture, errno_capture;
344	int ret_output, errno_output;
345	int ret_video_overlay, errno_video_overlay;
346	int ret_vbi_capture, errno_vbi_capture;
347	int ret_vbi_output, errno_vbi_output;
348	int ret_sliced_vbi_capture, errno_sliced_vbi_capture;
349	int ret_sliced_vbi_output, errno_sliced_vbi_output;
350	int ret_video_output_overlay, errno_video_output_overlay;
351	int ret_private, errno_private;
352	int ret_null, errno_null;
353	struct v4l2_fmtdesc format;
354
355	memset(&format, 0xff, sizeof(format));
356	format.index = 0;
357	format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
358	ret_capture = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
359	errno_capture = errno;
360
361	dprintf("\t%s:%u: VIDIOC_ENUM_FMT, ret_capture=%i, errno_capture=%i\n",
362		__FILE__, __LINE__, ret_capture, errno_capture);
363
364	memset(&format, 0xff, sizeof(format));
365	format.index = 0;
366	format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
367	ret_output = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
368	errno_output = errno;
369
370	dprintf("\t%s:%u: VIDIOC_ENUM_FMT, ret_output=%i, errno_output=%i\n",
371		__FILE__, __LINE__, ret_output, errno_output);
372
373	memset(&format, 0xff, sizeof(format));
374	format.index = 0;
375	format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
376	ret_video_overlay = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
377	errno_video_overlay = errno;
378
379	dprintf
380	    ("\t%s:%u: VIDIOC_ENUM_FMT, ret_video_overlay=%i, errno_video_overlay=%i\n",
381	     __FILE__, __LINE__, ret_video_overlay, errno_video_overlay);
382
383	memset(&format, 0xff, sizeof(format));
384	format.index = 0;
385	format.type = V4L2_BUF_TYPE_VBI_CAPTURE;
386	ret_vbi_capture = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
387	errno_vbi_capture = errno;
388
389	dprintf
390	    ("\t%s:%u: VIDIOC_ENUM_FMT, ret_vbi_capture=%i, errno_vbi_capture=%i\n",
391	     __FILE__, __LINE__, ret_vbi_capture, errno_vbi_capture);
392
393	memset(&format, 0xff, sizeof(format));
394	format.index = 0;
395	format.type = V4L2_BUF_TYPE_VBI_OUTPUT;
396	ret_vbi_output = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
397	errno_vbi_output = errno;
398
399	dprintf
400	    ("\t%s:%u: VIDIOC_ENUM_FMT, ret_vbi_output=%i, errno_vbi_output=%i\n",
401	     __FILE__, __LINE__, ret_vbi_output, errno_vbi_output);
402
403	memset(&format, 0xff, sizeof(format));
404	format.index = 0;
405	format.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
406	ret_sliced_vbi_capture =
407	    ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
408	errno_sliced_vbi_capture = errno;
409
410	dprintf
411	    ("\t%s:%u: VIDIOC_ENUM_FMT, ret_sliced_vbi_capture=%i, errno_sliced_vbi_capture=%i\n",
412	     __FILE__, __LINE__, ret_sliced_vbi_capture,
413	     errno_sliced_vbi_capture);
414
415	memset(&format, 0xff, sizeof(format));
416	format.index = 0;
417	format.type = V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
418	ret_sliced_vbi_output = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
419	errno_sliced_vbi_output = errno;
420
421	dprintf
422	    ("\t%s:%u: VIDIOC_ENUM_FMT, ret_sliced_vbi_output=%i, errno_sliced_vbi_output=%i\n",
423	     __FILE__, __LINE__, ret_sliced_vbi_output,
424	     errno_sliced_vbi_output);
425
426	memset(&format, 0xff, sizeof(format));
427	format.index = 0;
428	format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY;
429	ret_video_output_overlay =
430	    ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
431	errno_video_output_overlay = errno;
432
433	dprintf
434	    ("\t%s:%u: VIDIOC_ENUM_FMT, ret_video_output_overlay=%i, errno_video_output_overlay=%i\n",
435	     __FILE__, __LINE__, ret_video_output_overlay,
436	     errno_video_output_overlay);
437
438	memset(&format, 0xff, sizeof(format));
439	format.index = 0;
440	format.type = V4L2_BUF_TYPE_PRIVATE;
441	ret_private = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, &format);
442	errno_private = errno;
443
444	dprintf("\t%s:%u: VIDIOC_ENUM_FMT, ret_private=%i, errno_private=%i\n",
445		__FILE__, __LINE__, ret_private, errno_private);
446
447	ret_null = ioctl(get_video_fd(), VIDIOC_ENUM_FMT, NULL);
448	errno_null = errno;
449
450	dprintf("\t%s:%u: VIDIOC_ENUM_FMT, ret_null=%i, errno_null=%i\n",
451		__FILE__, __LINE__, ret_null, errno_null);
452
453	if (ret_capture == 0 || ret_output == 0 ||
454	    ret_video_overlay == 0 || ret_vbi_capture == 0 ||
455	    ret_vbi_output == 0 || ret_sliced_vbi_capture == 0 ||
456	    ret_sliced_vbi_output == 0 || ret_video_output_overlay == 0 ||
457	    ret_private == 0) {
458		CU_ASSERT_EQUAL(ret_null, -1);
459		CU_ASSERT_EQUAL(errno_null, EFAULT);
460	} else {
461		CU_ASSERT_EQUAL(ret_capture, -1);
462		CU_ASSERT_EQUAL(errno_null, EINVAL);
463		CU_ASSERT_EQUAL(ret_output, -1);
464		CU_ASSERT_EQUAL(errno_output, EINVAL);
465		CU_ASSERT_EQUAL(ret_video_overlay, -1);
466		CU_ASSERT_EQUAL(errno_video_overlay, EINVAL);
467		CU_ASSERT_EQUAL(ret_vbi_capture, -1);
468		CU_ASSERT_EQUAL(errno_vbi_capture, EINVAL);
469		CU_ASSERT_EQUAL(ret_vbi_output, -1);
470		CU_ASSERT_EQUAL(errno_vbi_output, EINVAL);
471		CU_ASSERT_EQUAL(ret_sliced_vbi_capture, -1);
472		CU_ASSERT_EQUAL(errno_sliced_vbi_capture, EINVAL);
473		CU_ASSERT_EQUAL(ret_sliced_vbi_output, -1);
474		CU_ASSERT_EQUAL(errno_sliced_vbi_output, EINVAL);
475		CU_ASSERT_EQUAL(ret_video_output_overlay, -1);
476		CU_ASSERT_EQUAL(errno_video_output_overlay, EINVAL);
477		CU_ASSERT_EQUAL(ret_private, -1);
478		CU_ASSERT_EQUAL(errno_private, EINVAL);
479		CU_ASSERT_EQUAL(ret_null, -1);
480		CU_ASSERT_EQUAL(errno_null, EINVAL);
481	}
482
483}
484