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
do_enumerate_formats(enum v4l2_buf_type type)42 static 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
test_VIDIOC_ENUM_FMT()119 void 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
test_VIDIOC_ENUM_FMT_S32_MAX()132 void 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
test_VIDIOC_ENUM_FMT_S32_MAX_1()160 void 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
test_VIDIOC_ENUM_FMT_U32_MAX()188 void 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
test_VIDIOC_ENUM_FMT_invalid_type()216 void 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
test_VIDIOC_ENUM_FMT_NULL()341 void 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