1 /*
2 * v4l-test: Test environment for Video For Linux Two API
3 *
4 * 29 Mar 2009 0.2 Comments updated
5 * 18 Mar 2009 0.1 First release
6 *
7 * Written by M�rton N�meth <nm127@freemail.hu>
8 * Released under GPL
9 */
10
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include <sys/ioctl.h>
17 #include <errno.h>
18 #include <string.h>
19
20 #include <linux/videodev2.h>
21 #include <linux/errno.h>
22
23 #include <CUnit/CUnit.h>
24
25 #include "v4l2_test.h"
26 #include "dev_video.h"
27 #include "video_limits.h"
28
29 #include "test_VIDIOC_PARM.h"
30
valid_v4l2_captureparm_capability(__u32 capability)31 int valid_v4l2_captureparm_capability(__u32 capability)
32 {
33 int valid = 0;
34
35 if ((capability & ~(V4L2_CAP_TIMEPERFRAME)) == 0) {
36 valid = 1;
37 } else {
38 valid = 0;
39 }
40 return valid;
41 }
42
valid_v4l2_outputparm_capability(__u32 capability)43 int valid_v4l2_outputparm_capability(__u32 capability)
44 {
45 int valid = 0;
46
47 if ((capability & ~(V4L2_CAP_TIMEPERFRAME)) == 0) {
48 valid = 1;
49 } else {
50 valid = 0;
51 }
52 return valid;
53 }
54
valid_v4l2_captureparm_capturemode(__u32 capturemode)55 int valid_v4l2_captureparm_capturemode(__u32 capturemode)
56 {
57 int valid = 0;
58
59 if ((capturemode & ~(V4L2_MODE_HIGHQUALITY)) == 0) {
60 valid = 1;
61 } else {
62 valid = 0;
63 }
64 return valid;
65 }
66
valid_v4l2_outputparm_outputpmode(__u32 outputmode)67 int valid_v4l2_outputparm_outputpmode(__u32 outputmode)
68 {
69 int valid = 0;
70
71 if ((outputmode & ~(V4L2_MODE_HIGHQUALITY)) == 0) {
72 valid = 1;
73 } else {
74 valid = 0;
75 }
76 return valid;
77 }
78
do_get_param(enum v4l2_buf_type type)79 static void do_get_param(enum v4l2_buf_type type)
80 {
81 int ret_get, errno_get;
82 struct v4l2_streamparm parm;
83 struct v4l2_streamparm parm2;
84
85 memset(&parm, 0xff, sizeof(parm));
86 parm.type = type;
87 ret_get = ioctl(get_video_fd(), VIDIOC_G_PARM, &parm);
88 errno_get = errno;
89
90 dprintf("\t%s:%u: VIDIOC_G_PARM, type=%i, ret_get=%i, errno_get=%i\n",
91 __FILE__, __LINE__, type, ret_get, errno_get);
92
93 if (ret_get == 0) {
94 CU_ASSERT_EQUAL(ret_get, 0);
95 CU_ASSERT_EQUAL(parm.type, type);
96
97 switch (parm.type) {
98 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
99 dprintf("\t%s:%u: { .type=%i, parm.capture = { "
100 ".capability = 0x%X, "
101 ".capturemode = 0x%X, "
102 ".timeperframe = { .numerator = %u, .denominator = %u }, "
103 ".extendedmode = %u, "
104 ".readbuffers = %u, "
105 "reserved[] = { 0x%X, 0x%X, 0x%X, 0x%X }}}\n",
106 __FILE__, __LINE__,
107 parm.type,
108 parm.parm.capture.capability,
109 parm.parm.capture.capturemode,
110 parm.parm.capture.timeperframe.numerator,
111 parm.parm.capture.timeperframe.denominator,
112 parm.parm.capture.extendedmode,
113 parm.parm.capture.readbuffers,
114 parm.parm.capture.reserved[0],
115 parm.parm.capture.reserved[1],
116 parm.parm.capture.reserved[2],
117 parm.parm.capture.reserved[3]
118 );
119
120 CU_ASSERT(valid_v4l2_captureparm_capability
121 (parm.parm.capture.capability));
122 CU_ASSERT(valid_v4l2_captureparm_capturemode
123 (parm.parm.capture.capturemode));
124
125 if (parm.parm.capture.
126 capability & V4L2_CAP_TIMEPERFRAME) {
127 //CU_ASSERT_EQUAL(parm.parm.capture.timeperframe.numerator, ???);
128 //CU_ASSERT_EQUAL(parm.parm.capture.timeperframe.denominator, ???);
129 CU_ASSERT(parm.parm.capture.timeperframe.
130 denominator != 0);
131 // TODO: timerperframe: check struct v4l2_standard frameperiod field
132 } else {
133 //CU_ASSERT_EQUAL(parm.parm.capture.timeperframe.numerator, 0);
134 //CU_ASSERT_EQUAL(parm.parm.capture.timeperframe.denominator, 0);
135 CU_ASSERT(parm.parm.output.timeperframe.
136 denominator != 0);
137 }
138
139 //CU_ASSERT_EQUAL(parm.parm.capture.extendedmode, ???);
140 //CU_ASSERT_EQUAL(parm.parm.capture.readbuffers, ???);
141
142 CU_ASSERT_EQUAL(parm.parm.capture.reserved[0], 0);
143 CU_ASSERT_EQUAL(parm.parm.capture.reserved[1], 0);
144 CU_ASSERT_EQUAL(parm.parm.capture.reserved[2], 0);
145 CU_ASSERT_EQUAL(parm.parm.capture.reserved[3], 0);
146 break;
147 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
148 dprintf("\t%s:%u: { .type=%i, parm.output = { "
149 ".capability = 0x%X, "
150 ".outputmode = 0x%X, "
151 ".timeperframe = { .numerator = %u, .denominator = %u }, "
152 ".extendedmode = %u, "
153 ".writebuffers = %u, "
154 "reserved[] = { 0x%X, 0x%X, 0x%X, 0x%X }}}\n",
155 __FILE__, __LINE__,
156 parm.type,
157 parm.parm.output.capability,
158 parm.parm.output.outputmode,
159 parm.parm.output.timeperframe.numerator,
160 parm.parm.output.timeperframe.denominator,
161 parm.parm.output.extendedmode,
162 parm.parm.output.writebuffers,
163 parm.parm.output.reserved[0],
164 parm.parm.output.reserved[1],
165 parm.parm.output.reserved[2],
166 parm.parm.output.reserved[3]
167 );
168
169 CU_ASSERT(valid_v4l2_outputparm_capability
170 (parm.parm.output.capability));
171 CU_ASSERT(valid_v4l2_outputparm_outputpmode
172 (parm.parm.output.outputmode));
173
174 if (parm.parm.output.capability & V4L2_CAP_TIMEPERFRAME) {
175 //CU_ASSERT_EQUAL(parm.parm.output.timeperframe.numerator, ???);
176 //CU_ASSERT_EQUAL(parm.parm.output.timeperframe.denominator, ???);
177 CU_ASSERT(parm.parm.output.timeperframe.
178 denominator != 0);
179 // TODO: timerperframe: check struct v4l2_standard frameperiod field
180 } else {
181 //CU_ASSERT_EQUAL(parm.parm.output.timeperframe.numerator, 0);
182 //CU_ASSERT_EQUAL(parm.parm.output.timeperframe.denominator, 0);
183 CU_ASSERT(parm.parm.output.timeperframe.
184 denominator != 0);
185 }
186
187 //CU_ASSERT_EQUAL(parm.parm.output.extendedmode, ???);
188 //CU_ASSERT_EQUAL(parm.parm.output.writebuffers, ???);
189
190 CU_ASSERT_EQUAL(parm.parm.output.reserved[0], 0);
191 CU_ASSERT_EQUAL(parm.parm.output.reserved[1], 0);
192 CU_ASSERT_EQUAL(parm.parm.output.reserved[2], 0);
193 CU_ASSERT_EQUAL(parm.parm.output.reserved[3], 0);
194 break;
195 default:
196 ;
197 }
198
199 } else {
200 CU_ASSERT_EQUAL(ret_get, -1);
201 CU_ASSERT_EQUAL(errno_get, EINVAL);
202
203 /* check whether the parm structure is untouched */
204 memset(&parm2, 0xff, sizeof(parm2));
205 parm2.type = type;
206
207 CU_ASSERT_EQUAL(memcmp(&parm, &parm2, sizeof(parm)), 0);
208
209 }
210
211 }
212
test_VIDIOC_G_PARM()213 void test_VIDIOC_G_PARM()
214 {
215 do_get_param(V4L2_BUF_TYPE_VIDEO_CAPTURE);
216 do_get_param(V4L2_BUF_TYPE_VIDEO_OUTPUT);
217 do_get_param(V4L2_BUF_TYPE_PRIVATE);
218 }
219
do_get_param_invalid(enum v4l2_buf_type type)220 static void do_get_param_invalid(enum v4l2_buf_type type)
221 {
222 int ret_get, errno_get;
223 struct v4l2_streamparm parm;
224 struct v4l2_streamparm parm2;
225
226 memset(&parm, 0xff, sizeof(parm));
227 parm.type = type;
228 ret_get = ioctl(get_video_fd(), VIDIOC_G_PARM, &parm);
229 errno_get = errno;
230
231 dprintf("\t%s:%u: VIDIOC_G_PARM, type=%i, ret_get=%i, errno_get=%i\n",
232 __FILE__, __LINE__, type, ret_get, errno_get);
233
234 CU_ASSERT_EQUAL(ret_get, -1);
235 CU_ASSERT_EQUAL(errno_get, EINVAL);
236
237 /* check whether the parm structure is untouched */
238 memset(&parm2, 0xff, sizeof(parm2));
239 parm2.type = type;
240
241 CU_ASSERT_EQUAL(memcmp(&parm, &parm2, sizeof(parm)), 0);
242 }
243
test_VIDIOC_G_PARM_invalid()244 void test_VIDIOC_G_PARM_invalid()
245 {
246 do_get_param_invalid(S32_MIN);
247
248 /* check if 0x80000001 is not treated as 1 (V4L2_BUF_TYPE_VIDEO_CAPTURE) */
249 do_get_param_invalid(S32_MIN + 1);
250
251 /* check if 0x80000002 is not treated as 2 (V4L2_BUF_TYPE_VIDEO_OUTPUT) */
252 do_get_param_invalid(S32_MIN + 2);
253
254 do_get_param_invalid(S16_MIN);
255 do_get_param_invalid(0);
256 do_get_param_invalid(V4L2_BUF_TYPE_VIDEO_OVERLAY);
257 do_get_param_invalid(V4L2_BUF_TYPE_VBI_CAPTURE);
258 do_get_param_invalid(V4L2_BUF_TYPE_VBI_OUTPUT);
259 do_get_param_invalid(V4L2_BUF_TYPE_SLICED_VBI_CAPTURE);
260 do_get_param_invalid(V4L2_BUF_TYPE_SLICED_VBI_OUTPUT);
261 do_get_param_invalid(V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY);
262 do_get_param_invalid(V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY + 1);
263 do_get_param_invalid(V4L2_BUF_TYPE_PRIVATE - 1);
264 do_get_param_invalid(S16_MAX);
265 do_get_param_invalid(S32_MAX);
266 }
267
test_VIDIOC_G_PARM_NULL()268 void test_VIDIOC_G_PARM_NULL()
269 {
270 int ret_capture, errno_capture;
271 int ret_output, errno_output;
272 int ret_private, errno_private;
273 int ret_null, errno_null;
274 enum v4l2_buf_type type;
275 struct v4l2_streamparm parm;
276
277 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
278 memset(&parm, 0, sizeof(parm));
279 parm.type = type;
280 ret_capture = ioctl(get_video_fd(), VIDIOC_G_PARM, &parm);
281 errno_capture = errno;
282 dprintf
283 ("\t%s:%u: VIDIOC_G_PARM, type=%i, ret_capture=%i, errno_capture=%i\n",
284 __FILE__, __LINE__, type, ret_capture, errno_capture);
285
286 type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
287 memset(&parm, 0, sizeof(parm));
288 parm.type = type;
289 ret_output = ioctl(get_video_fd(), VIDIOC_G_PARM, &parm);
290 errno_output = errno;
291 dprintf
292 ("\t%s:%u: VIDIOC_G_PARM, type=%i, ret_output=%i, errno_output=%i\n",
293 __FILE__, __LINE__, type, ret_output, errno_output);
294
295 type = V4L2_BUF_TYPE_PRIVATE;
296 memset(&parm, 0, sizeof(parm));
297 parm.type = type;
298 ret_private = ioctl(get_video_fd(), VIDIOC_G_PARM, &parm);
299 errno_private = errno;
300 dprintf
301 ("\t%s:%u: VIDIOC_G_PARM, type=%i, ret_private=%i, errno_private=%i\n",
302 __FILE__, __LINE__, type, ret_private, errno_private);
303
304 ret_null = ioctl(get_video_fd(), VIDIOC_G_PARM, NULL);
305 errno_null = errno;
306 dprintf("\t%s:%u: VIDIOC_G_PARM, ret_null=%i, errno_null=%i\n",
307 __FILE__, __LINE__, ret_null, errno_null);
308
309 if (ret_capture == 0 || ret_output == 0 || ret_private == 0) {
310 /* if at least one type is supported, then the
311 * parameter shall be tested and the result shall be EFAULT
312 */
313 CU_ASSERT_EQUAL(ret_null, -1);
314 CU_ASSERT_EQUAL(errno_null, EFAULT);
315 } else {
316 CU_ASSERT_EQUAL(ret_capture, -1);
317 CU_ASSERT_EQUAL(errno_capture, EINVAL);
318 CU_ASSERT_EQUAL(ret_output, -1);
319 CU_ASSERT_EQUAL(errno_output, EINVAL);
320 CU_ASSERT_EQUAL(ret_private, -1);
321 CU_ASSERT_EQUAL(errno_private, EINVAL);
322 CU_ASSERT_EQUAL(ret_null, -1);
323 CU_ASSERT_EQUAL(errno_null, EINVAL);
324 }
325
326 }
327
328 /* TODO: test cases for VIDIOC_S_PARM */
329