test_VIDIOC_REQBUFS.c revision 7564c8a7cf3d94e2d84b52c6e50c14bed1650b91
1/*
2 * v4l-test: Test environment for Video For Linux Two API
3 *
4 *  7 May 2009  0.2  show_v4l2_*() function extracted to v4l2_show.c
5 * 29 Apr 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 "v4l2_show.h"
27#include "dev_video.h"
28#include "video_limits.h"
29
30#include "test_VIDIOC_REQBUFS.h"
31
32static void do_VIDIOC_REQBUFS_capture_mmap(__u32 count) {
33	int ret_cap, errno_cap;
34	int ret_req, errno_req;
35	struct v4l2_capability cap;
36	struct v4l2_requestbuffers reqbuf;
37	struct v4l2_requestbuffers reqbuf2;
38
39	memset(&cap, 0, sizeof(cap));
40
41	ret_cap = ioctl(get_video_fd(), VIDIOC_QUERYCAP, &cap);
42	errno_cap = errno;
43
44	memset(&reqbuf, 0xff, sizeof(reqbuf));
45	reqbuf.count = count;
46	reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
47	reqbuf.memory = V4L2_MEMORY_MMAP;
48
49	ret_req = ioctl(get_video_fd(), VIDIOC_REQBUFS, &reqbuf);
50	errno_req = errno;
51
52	dprintf("\t%s:%u: VIDIOC_REQBUF, count=%u, ret_req=%i, errno_req=%i\n",
53		__FILE__, __LINE__, count, ret_req, errno_req);
54
55	if (ret_cap == 0 &&
56	    (cap.capabilities & V4L2_CAP_STREAMING) &&
57	    (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
58
59		CU_ASSERT_EQUAL(ret_cap, 0);
60		CU_ASSERT(cap.capabilities & V4L2_CAP_STREAMING);
61
62		CU_ASSERT_EQUAL(ret_req, 0);
63		//CU_ASSERT_EQUAL(reqbuf.count, ???);
64		CU_ASSERT_EQUAL(reqbuf.type, V4L2_BUF_TYPE_VIDEO_CAPTURE);
65		CU_ASSERT_EQUAL(reqbuf.memory, V4L2_MEMORY_MMAP);
66		CU_ASSERT_EQUAL(reqbuf.reserved[0], 0);
67		CU_ASSERT_EQUAL(reqbuf.reserved[1], 0);
68
69	} else {
70		CU_ASSERT_EQUAL(ret_req, -1);
71		CU_ASSERT_EQUAL(errno_req, EINVAL);
72
73		memset(&reqbuf2, 0xff, sizeof(reqbuf2));
74		reqbuf2.count = count;
75		reqbuf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
76		reqbuf2.memory = V4L2_MEMORY_MMAP;
77
78		CU_ASSERT_EQUAL(memcmp(&reqbuf, &reqbuf2, sizeof(reqbuf)), 0);
79	}
80
81	if (ret_req == 0) {
82		show_v4l2_requestbuffers(&reqbuf);
83	}
84
85}
86
87void test_VIDIOC_REQBUFS_capture_mmap() {
88	do_VIDIOC_REQBUFS_capture_mmap(0);
89	do_VIDIOC_REQBUFS_capture_mmap(1);
90	do_VIDIOC_REQBUFS_capture_mmap(2);
91	do_VIDIOC_REQBUFS_capture_mmap(3);
92	do_VIDIOC_REQBUFS_capture_mmap(4);
93	do_VIDIOC_REQBUFS_capture_mmap((__u32)S16_MIN);
94	do_VIDIOC_REQBUFS_capture_mmap((__u32)S16_MAX);
95	do_VIDIOC_REQBUFS_capture_mmap(U32_MAX);
96	do_VIDIOC_REQBUFS_capture_mmap(0);
97}
98
99static void do_VIDIOC_REQBUFS_capture_userptr(__u32 count) {
100	int ret_cap, errno_cap;
101	int ret_req, errno_req;
102	struct v4l2_capability cap;
103	struct v4l2_requestbuffers reqbuf;
104	struct v4l2_requestbuffers reqbuf2;
105
106	memset(&cap, 0, sizeof(cap));
107
108	ret_cap = ioctl(get_video_fd(), VIDIOC_QUERYCAP, &cap);
109	errno_cap = errno;
110
111	memset(&reqbuf, 0xff, sizeof(reqbuf));
112	reqbuf.count = count;
113	reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
114	reqbuf.memory = V4L2_MEMORY_USERPTR;
115
116	ret_req = ioctl(get_video_fd(), VIDIOC_REQBUFS, &reqbuf);
117	errno_req = errno;
118
119	dprintf("\t%s:%u: VIDIOC_REQBUF, count=%u, ret_req=%i, errno_req=%i\n",
120		__FILE__, __LINE__, count, ret_req, errno_req);
121
122	if (ret_cap == 0 &&
123	    (cap.capabilities & V4L2_CAP_STREAMING) &&
124	    (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) &&
125	    ret_req == 0
126	    ) {
127		CU_ASSERT_EQUAL(ret_cap, 0);
128		CU_ASSERT(cap.capabilities & V4L2_CAP_STREAMING);
129
130		CU_ASSERT_EQUAL(ret_req, 0);
131		//CU_ASSERT_EQUAL(reqbuf.count, ???);
132		CU_ASSERT_EQUAL(reqbuf.type, V4L2_BUF_TYPE_VIDEO_CAPTURE);
133		CU_ASSERT_EQUAL(reqbuf.memory, V4L2_MEMORY_USERPTR);
134		CU_ASSERT_EQUAL(reqbuf.reserved[0], 0);
135		CU_ASSERT_EQUAL(reqbuf.reserved[1], 0);
136
137	} else {
138		CU_ASSERT_EQUAL(ret_req, -1);
139		CU_ASSERT_EQUAL(errno_req, EINVAL);
140
141		memset(&reqbuf2, 0xff, sizeof(reqbuf2));
142		reqbuf2.count = count;
143		reqbuf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
144		reqbuf2.memory = V4L2_MEMORY_USERPTR;
145
146		CU_ASSERT_EQUAL(memcmp(&reqbuf, &reqbuf2, sizeof(reqbuf)), 0);
147	}
148
149	if (ret_req == 0) {
150		show_v4l2_requestbuffers(&reqbuf);
151	}
152
153}
154
155void test_VIDIOC_REQBUFS_capture_userptr() {
156	do_VIDIOC_REQBUFS_capture_userptr(0);
157	do_VIDIOC_REQBUFS_capture_userptr(1);
158	do_VIDIOC_REQBUFS_capture_userptr((__u32)S16_MIN);
159	do_VIDIOC_REQBUFS_capture_userptr((__u32)S16_MAX);
160	do_VIDIOC_REQBUFS_capture_userptr(U32_MAX);
161	do_VIDIOC_REQBUFS_capture_userptr(0);
162}
163
164static void do_VIDIOC_REQBUFS_output_mmap(__u32 count) {
165	int ret_cap, errno_cap;
166	int ret_req, errno_req;
167	struct v4l2_capability cap;
168	struct v4l2_requestbuffers reqbuf;
169	struct v4l2_requestbuffers reqbuf2;
170
171	memset(&cap, 0, sizeof(cap));
172
173	ret_cap = ioctl(get_video_fd(), VIDIOC_QUERYCAP, &cap);
174	errno_cap = errno;
175
176	memset(&reqbuf, 0xff, sizeof(reqbuf));
177	reqbuf.count = count;
178	reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
179	reqbuf.memory = V4L2_MEMORY_MMAP;
180
181	ret_req = ioctl(get_video_fd(), VIDIOC_REQBUFS, &reqbuf);
182	errno_req = errno;
183
184	dprintf("\t%s:%u: VIDIOC_REQBUF, count=%u, ret_req=%i, errno_req=%i\n",
185		__FILE__, __LINE__, count, ret_req, errno_req);
186
187	if (ret_cap == 0 &&
188	    (cap.capabilities & V4L2_CAP_STREAMING) &&
189	    (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) {
190
191		CU_ASSERT_EQUAL(ret_cap, 0);
192		CU_ASSERT(cap.capabilities & V4L2_CAP_STREAMING);
193
194		CU_ASSERT_EQUAL(ret_req, 0);
195		//CU_ASSERT_EQUAL(reqbuf.count, ???);
196		CU_ASSERT_EQUAL(reqbuf.type, V4L2_BUF_TYPE_VIDEO_OUTPUT);
197		CU_ASSERT_EQUAL(reqbuf.memory, V4L2_MEMORY_MMAP);
198		CU_ASSERT_EQUAL(reqbuf.reserved[0], 0);
199		CU_ASSERT_EQUAL(reqbuf.reserved[1], 0);
200
201	} else {
202		CU_ASSERT_EQUAL(ret_req, -1);
203		CU_ASSERT_EQUAL(errno_req, EINVAL);
204
205		memset(&reqbuf2, 0xff, sizeof(reqbuf2));
206		reqbuf2.count = count;
207		reqbuf2.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
208		reqbuf2.memory = V4L2_MEMORY_MMAP;
209
210		CU_ASSERT_EQUAL(memcmp(&reqbuf, &reqbuf2, sizeof(reqbuf)), 0);
211	}
212
213	if (ret_req == 0) {
214		show_v4l2_requestbuffers(&reqbuf);
215	}
216
217}
218
219void test_VIDIOC_REQBUFS_output_mmap() {
220	do_VIDIOC_REQBUFS_output_mmap(0);
221	do_VIDIOC_REQBUFS_output_mmap(1);
222	do_VIDIOC_REQBUFS_output_mmap(2);
223	do_VIDIOC_REQBUFS_output_mmap(3);
224	do_VIDIOC_REQBUFS_output_mmap(4);
225	do_VIDIOC_REQBUFS_output_mmap((__u32)S16_MIN);
226	do_VIDIOC_REQBUFS_output_mmap((__u32)S16_MAX);
227	do_VIDIOC_REQBUFS_output_mmap(U32_MAX);
228	do_VIDIOC_REQBUFS_output_mmap(0);
229}
230
231static void do_VIDIOC_REQBUFS_output_userptr(__u32 count) {
232	int ret_cap, errno_cap;
233	int ret_req, errno_req;
234	struct v4l2_capability cap;
235	struct v4l2_requestbuffers reqbuf;
236	struct v4l2_requestbuffers reqbuf2;
237
238	memset(&cap, 0, sizeof(cap));
239
240	ret_cap = ioctl(get_video_fd(), VIDIOC_QUERYCAP, &cap);
241	errno_cap = errno;
242
243	memset(&reqbuf, 0xff, sizeof(reqbuf));
244	reqbuf.count = count;
245	reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
246	reqbuf.memory = V4L2_MEMORY_USERPTR;
247
248	ret_req = ioctl(get_video_fd(), VIDIOC_REQBUFS, &reqbuf);
249	errno_req = errno;
250
251	dprintf("\t%s:%u: VIDIOC_REQBUF, count=%u, ret_req=%i, errno_req=%i\n",
252		__FILE__, __LINE__, count, ret_req, errno_req);
253
254	if (ret_cap == 0 &&
255	    (cap.capabilities & V4L2_CAP_STREAMING) &&
256	    (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) &&
257	    ret_req == 0
258	    ) {
259		CU_ASSERT_EQUAL(ret_cap, 0);
260		CU_ASSERT(cap.capabilities & V4L2_CAP_STREAMING);
261
262		CU_ASSERT_EQUAL(ret_req, 0);
263		//CU_ASSERT_EQUAL(reqbuf.count, ???);
264		CU_ASSERT_EQUAL(reqbuf.type, V4L2_BUF_TYPE_VIDEO_OUTPUT);
265		CU_ASSERT_EQUAL(reqbuf.memory, V4L2_MEMORY_USERPTR);
266		CU_ASSERT_EQUAL(reqbuf.reserved[0], 0);
267		CU_ASSERT_EQUAL(reqbuf.reserved[1], 0);
268
269	} else {
270		CU_ASSERT_EQUAL(ret_req, -1);
271		CU_ASSERT_EQUAL(errno_req, EINVAL);
272
273		memset(&reqbuf2, 0xff, sizeof(reqbuf2));
274		reqbuf2.count = count;
275		reqbuf2.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
276		reqbuf2.memory = V4L2_MEMORY_USERPTR;
277
278		CU_ASSERT_EQUAL(memcmp(&reqbuf, &reqbuf2, sizeof(reqbuf)), 0);
279	}
280
281	if (ret_req == 0) {
282		show_v4l2_requestbuffers(&reqbuf);
283	}
284
285}
286
287void test_VIDIOC_REQBUFS_output_userptr() {
288	do_VIDIOC_REQBUFS_output_userptr(0);
289	do_VIDIOC_REQBUFS_output_userptr(1);
290	do_VIDIOC_REQBUFS_output_userptr((__u32)S16_MIN);
291	do_VIDIOC_REQBUFS_output_userptr((__u32)S16_MAX);
292	do_VIDIOC_REQBUFS_output_userptr(U32_MAX);
293	do_VIDIOC_REQBUFS_output_userptr(0);
294}
295
296static void do_VIDIOC_REQBUFS_invalid_memory(enum v4l2_buf_type type, enum v4l2_memory memory) {
297	int ret_req, errno_req;
298	struct v4l2_requestbuffers reqbuf;
299	struct v4l2_requestbuffers reqbuf2;
300
301	memset(&reqbuf, 0xff, sizeof(reqbuf));
302	reqbuf.count = 0;
303	reqbuf.type = type;
304	reqbuf.memory = memory;
305
306	ret_req = ioctl(get_video_fd(), VIDIOC_REQBUFS, &reqbuf);
307	errno_req = errno;
308
309	dprintf("\t%s:%u: VIDIOC_REQBUF, type=0%x, ret_req=%i, errno_req=%i\n",
310		__FILE__, __LINE__, type, ret_req, errno_req);
311
312	CU_ASSERT_EQUAL(ret_req, -1);
313	CU_ASSERT_EQUAL(errno_req, EINVAL);
314
315	memset(&reqbuf2, 0xff, sizeof(reqbuf2));
316	reqbuf2.count = 0;
317	reqbuf2.type = type;
318	reqbuf2.memory = memory;
319
320	CU_ASSERT_EQUAL(memcmp(&reqbuf, &reqbuf2, sizeof(reqbuf)), 0);
321
322	if (ret_req == 0) {
323		show_v4l2_requestbuffers(&reqbuf);
324	}
325
326}
327
328void test_VIDIOC_REQBUFS_invalid_memory_capture() {
329	do_VIDIOC_REQBUFS_invalid_memory(V4L2_BUF_TYPE_VIDEO_CAPTURE, SINT_MIN);
330	do_VIDIOC_REQBUFS_invalid_memory(V4L2_BUF_TYPE_VIDEO_CAPTURE, 0);
331	do_VIDIOC_REQBUFS_invalid_memory(V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_MEMORY_OVERLAY);
332	do_VIDIOC_REQBUFS_invalid_memory(V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_MEMORY_OVERLAY+1);
333	do_VIDIOC_REQBUFS_invalid_memory(V4L2_BUF_TYPE_VIDEO_CAPTURE, SINT_MAX);
334}
335
336void test_VIDIOC_REQBUFS_invalid_memory_output() {
337	do_VIDIOC_REQBUFS_invalid_memory(V4L2_BUF_TYPE_VIDEO_OUTPUT, SINT_MIN);
338	do_VIDIOC_REQBUFS_invalid_memory(V4L2_BUF_TYPE_VIDEO_OUTPUT, 0);
339	do_VIDIOC_REQBUFS_invalid_memory(V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_MEMORY_OVERLAY);
340	do_VIDIOC_REQBUFS_invalid_memory(V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_MEMORY_OVERLAY+1);
341	do_VIDIOC_REQBUFS_invalid_memory(V4L2_BUF_TYPE_VIDEO_OUTPUT, SINT_MAX);
342}
343
344
345static void do_VIDIOC_REQBUFS_invalid_type(enum v4l2_memory memory, enum v4l2_buf_type type) {
346	int ret_req, errno_req;
347	struct v4l2_requestbuffers reqbuf;
348	struct v4l2_requestbuffers reqbuf2;
349	__u32 count;
350
351	count = 1;
352
353	memset(&reqbuf, 0xff, sizeof(reqbuf));
354	reqbuf.count = count;
355	reqbuf.type = type;
356	reqbuf.memory = memory;
357
358	ret_req = ioctl(get_video_fd(), VIDIOC_REQBUFS, &reqbuf);
359	errno_req = errno;
360
361	dprintf("\t%s:%u: VIDIOC_REQBUF, type=0x%x, memory=%i, ret_req=%i, errno_req=%i\n",
362		__FILE__, __LINE__, type, memory, ret_req, errno_req);
363
364	CU_ASSERT_EQUAL(ret_req, -1);
365	CU_ASSERT_EQUAL(errno_req, EINVAL);
366
367	memset(&reqbuf2, 0xff, sizeof(reqbuf2));
368	reqbuf2.count = count;
369	reqbuf2.type = type;
370	reqbuf2.memory = memory;
371
372	CU_ASSERT_EQUAL(memcmp(&reqbuf, &reqbuf2, sizeof(reqbuf)), 0);
373
374	if (ret_req == 0) {
375		show_v4l2_requestbuffers(&reqbuf);
376	}
377}
378
379void test_VIDIOC_REQUBUFS_invalid_type_mmap() {
380	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, 0);
381	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, V4L2_BUF_TYPE_VIDEO_OVERLAY);
382	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, V4L2_BUF_TYPE_VBI_CAPTURE);
383	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, V4L2_BUF_TYPE_VBI_OUTPUT);
384	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, V4L2_BUF_TYPE_SLICED_VBI_CAPTURE);
385	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, V4L2_BUF_TYPE_SLICED_VBI_OUTPUT);
386	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY);
387	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, V4L2_BUF_TYPE_PRIVATE-1);
388	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, V4L2_BUF_TYPE_PRIVATE);
389	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, V4L2_BUF_TYPE_PRIVATE+1);
390	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, S32_MAX);
391	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, (__s32)((__u32)S32_MAX+1));
392	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, U32_MAX-1);
393	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_MMAP, U32_MAX);
394
395}
396
397void test_VIDIOC_REQUBUFS_invalid_type_userptr() {
398	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, 0);
399	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, V4L2_BUF_TYPE_VIDEO_OVERLAY);
400	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, V4L2_BUF_TYPE_VBI_CAPTURE);
401	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, V4L2_BUF_TYPE_VBI_OUTPUT);
402	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, V4L2_BUF_TYPE_SLICED_VBI_CAPTURE);
403	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, V4L2_BUF_TYPE_SLICED_VBI_OUTPUT);
404	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY);
405	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, V4L2_BUF_TYPE_PRIVATE-1);
406	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, V4L2_BUF_TYPE_PRIVATE);
407	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, V4L2_BUF_TYPE_PRIVATE+1);
408	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, S32_MAX);
409	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, (__s32)((__u32)S32_MAX+1));
410	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, U32_MAX-1);
411	do_VIDIOC_REQBUFS_invalid_type(V4L2_MEMORY_USERPTR, U32_MAX);
412
413}
414