~ubuntu-branches/ubuntu/oneiric/v4l-utils/oneiric

« back to all changes in this revision

Viewing changes to utils/v4l2-compliance/v4l2-test-formats.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-07-22 13:58:48 UTC
  • mfrom: (11.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20110722135848-tju3x5jlpa4e9by5
Tags: 0.8.5-1ubuntu1
debian/control: Drop ia32-libs-dev build dependency; we don't have this in
Ubuntu, and ia32-libs is in universe.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    V4L2 API format ioctl tests.
 
3
 
 
4
    Copyright (C) 2011  Hans Verkuil <hans.verkuil@cisco.com>
 
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
#include <unistd.h>
 
22
#include <stdlib.h>
 
23
#include <stdio.h>
 
24
#include <string.h>
 
25
#include <inttypes.h>
 
26
#include <sys/types.h>
 
27
#include <sys/stat.h>
 
28
#include <fcntl.h>
 
29
#include <ctype.h>
 
30
#include <errno.h>
 
31
#include <sys/ioctl.h>
 
32
#include <assert.h>
 
33
#include "v4l2-compliance.h"
 
34
 
 
35
static const __u32 buftype2cap[] = {
 
36
        0,
 
37
        V4L2_CAP_VIDEO_CAPTURE,
 
38
        V4L2_CAP_VIDEO_OUTPUT,
 
39
        V4L2_CAP_VIDEO_OVERLAY,
 
40
        V4L2_CAP_VBI_CAPTURE,
 
41
        V4L2_CAP_VBI_OUTPUT,
 
42
        V4L2_CAP_SLICED_VBI_CAPTURE,
 
43
        V4L2_CAP_SLICED_VBI_OUTPUT,
 
44
        V4L2_CAP_VIDEO_OUTPUT_OVERLAY,
 
45
        // To be discussed
 
46
        V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_CAPTURE,
 
47
        V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_OUTPUT,
 
48
};
 
49
 
 
50
static int testEnumFrameIntervals(struct node *node, __u32 pixfmt, __u32 w, __u32 h, bool valid)
 
51
{
 
52
        struct v4l2_frmivalenum frmival;
 
53
        struct v4l2_frmival_stepwise *sw = &frmival.stepwise;
 
54
        bool found_stepwise = false;
 
55
        unsigned f = 0;
 
56
        int ret;
 
57
 
 
58
        for (;;) {
 
59
                memset(&frmival, 0xff, sizeof(frmival));
 
60
                frmival.index = f;
 
61
                frmival.pixel_format = pixfmt;
 
62
                frmival.width = w;
 
63
                frmival.height = h;
 
64
 
 
65
                ret = doioctl(node, VIDIOC_ENUM_FRAMEINTERVALS, &frmival);
 
66
                if (f == 0 && ret == EINVAL) {
 
67
                        if (valid)
 
68
                                warn("found framesize %dx%d, but no frame intervals\n", w, h);
 
69
                        return -ENOSYS;
 
70
                }
 
71
                if (ret == EINVAL)
 
72
                        break;
 
73
                if (ret)
 
74
                        return fail("expected EINVAL, but got %d when enumerating frameinterval %d\n", ret, f);
 
75
                ret = check_0(frmival.reserved, sizeof(frmival.reserved));
 
76
                if (ret)
 
77
                        return fail("frmival.reserved not zeroed\n");
 
78
                if (frmival.pixel_format != pixfmt || frmival.index != f ||
 
79
                                frmival.width != w || frmival.height != h)
 
80
                        return fail("frmival.pixel_format, index, width or height changed\n");
 
81
                switch (frmival.type) {
 
82
                case V4L2_FRMIVAL_TYPE_DISCRETE:
 
83
                        ret = check_fract(&frmival.discrete);
 
84
                        if (found_stepwise)
 
85
                                return fail("mixing discrete and stepwise is not allowed\n");
 
86
                        break;
 
87
                case V4L2_FRMIVAL_TYPE_CONTINUOUS:
 
88
                        if (sw->step.numerator != 1 || sw->step.denominator != 1)
 
89
                                return fail("invalid step for continuous frameinterval\n");
 
90
                        /* fallthrough */
 
91
                case V4L2_FRMIVAL_TYPE_STEPWISE:
 
92
                        if (frmival.index)
 
93
                                return fail("index must be 0 for stepwise/continuous frameintervals\n");
 
94
                        found_stepwise = true;
 
95
                        ret = check_fract(&sw->min);
 
96
                        if (ret == 0)
 
97
                                ret = check_fract(&sw->max);
 
98
                        if (ret == 0)
 
99
                                ret = check_fract(&sw->step);
 
100
                        if (ret)
 
101
                                return fail("invalid min, max or step for frameinterval %d\n", f);
 
102
                        if (fract2f(&sw->min) > fract2f(&sw->max))
 
103
                                return fail("min > max\n");
 
104
                        if (fract2f(&sw->step) > fract2f(&sw->max) - fract2f(&sw->min))
 
105
                                return fail("step > (max - min)\n");
 
106
                        break;
 
107
                default:
 
108
                        return fail("frmival.type is invalid\n");
 
109
                }
 
110
                
 
111
                f++;
 
112
        }
 
113
        if (!valid)
 
114
                return fail("found frame intervals for invalid size %dx%d\n", w, h);
 
115
        info("found %d frameintervals for pixel format %08x and size %dx%d\n", f, pixfmt, w, h);
 
116
        return 0;
 
117
}
 
118
 
 
119
static int testEnumFrameSizes(struct node *node, __u32 pixfmt)
 
120
{
 
121
        struct v4l2_frmsizeenum frmsize;
 
122
        struct v4l2_frmsize_stepwise *sw = &frmsize.stepwise;
 
123
        bool found_stepwise = false;
 
124
        unsigned f = 0;
 
125
        int ret;
 
126
 
 
127
        for (;;) {
 
128
                memset(&frmsize, 0xff, sizeof(frmsize));
 
129
                frmsize.index = f;
 
130
                frmsize.pixel_format = pixfmt;
 
131
 
 
132
                ret = doioctl(node, VIDIOC_ENUM_FRAMESIZES, &frmsize);
 
133
                if (f == 0 && ret == EINVAL)
 
134
                        return -ENOSYS;
 
135
                if (ret == EINVAL)
 
136
                        break;
 
137
                if (ret)
 
138
                        return fail("expected EINVAL, but got %d when enumerating framesize %d\n", ret, f);
 
139
                ret = check_0(frmsize.reserved, sizeof(frmsize.reserved));
 
140
                if (ret)
 
141
                        return fail("frmsize.reserved not zeroed\n");
 
142
                if (frmsize.pixel_format != pixfmt || frmsize.index != f)
 
143
                        return fail("frmsize.pixel_format or index changed\n");
 
144
                switch (frmsize.type) {
 
145
                case V4L2_FRMSIZE_TYPE_DISCRETE:
 
146
                        if (frmsize.discrete.width == 0 || frmsize.discrete.height == 0)
 
147
                                return fail("invalid width/height for discrete framesize\n");
 
148
                        if (found_stepwise)
 
149
                                return fail("mixing discrete and stepwise is not allowed\n");
 
150
                        ret = testEnumFrameIntervals(node, pixfmt,
 
151
                                        frmsize.discrete.width, frmsize.discrete.height, true);
 
152
                        if (ret > 0)
 
153
                                return ret;
 
154
                        ret = testEnumFrameIntervals(node, pixfmt,
 
155
                                        frmsize.discrete.width + 1, frmsize.discrete.height, false);
 
156
                        if (ret > 0)
 
157
                                return ret;
 
158
                        break;
 
159
                case V4L2_FRMSIZE_TYPE_CONTINUOUS:
 
160
                        if (frmsize.stepwise.step_width != 1 || frmsize.stepwise.step_height != 1)
 
161
                                return fail("invalid step_width/height for continuous framesize\n");
 
162
                        /* fallthrough */
 
163
                case V4L2_FRMSIZE_TYPE_STEPWISE:
 
164
                        if (frmsize.index)
 
165
                                return fail("index must be 0 for stepwise/continuous framesizes\n");
 
166
                        found_stepwise = true;
 
167
                        if (!sw->min_width || !sw->min_height || !sw->step_width || !sw->step_height)
 
168
                                return fail("0 for min_width/height or step_width/height\n");
 
169
                        if (sw->min_width > sw->max_width || sw->min_height > sw->max_height)
 
170
                                return fail("min_width/height > max_width/height\n");
 
171
                        if (sw->step_width > sw->max_width - sw->min_width ||
 
172
                            sw->step_height > sw->max_height - sw->min_height)
 
173
                                return fail("step > max - min for width or height\n");
 
174
                        ret = testEnumFrameIntervals(node, pixfmt,
 
175
                                        sw->min_width, sw->min_height, true);
 
176
                        if (ret > 0)
 
177
                                return ret;
 
178
                        ret = testEnumFrameIntervals(node, pixfmt,
 
179
                                        sw->max_width, sw->max_height, true);
 
180
                        if (ret > 0)
 
181
                                return ret;
 
182
                        ret = testEnumFrameIntervals(node, pixfmt,
 
183
                                        sw->min_width - 1, sw->min_height, false);
 
184
                        if (ret > 0)
 
185
                                return ret;
 
186
                        ret = testEnumFrameIntervals(node, pixfmt,
 
187
                                        sw->max_width, sw->max_height + 1, false);
 
188
                        if (ret > 0)
 
189
                                return ret;
 
190
                        break;
 
191
                default:
 
192
                        return fail("frmsize.type is invalid\n");
 
193
                }
 
194
                
 
195
                f++;
 
196
        }
 
197
        info("found %d framesizes for pixel format %08x\n", f, pixfmt);
 
198
        return 0;
 
199
}
 
200
 
 
201
static int testEnumFormatsType(struct node *node, enum v4l2_buf_type type)
 
202
{
 
203
        pixfmt_set &set = node->buftype_pixfmts[type];
 
204
        struct v4l2_fmtdesc fmtdesc;
 
205
        unsigned f = 0;
 
206
        int ret;
 
207
 
 
208
        for (;;) {
 
209
                memset(&fmtdesc, 0xff, sizeof(fmtdesc));
 
210
                fmtdesc.type = type;
 
211
                fmtdesc.index = f;
 
212
 
 
213
                ret = doioctl(node, VIDIOC_ENUM_FMT, &fmtdesc);
 
214
                if (f == 0 && ret == EINVAL)
 
215
                        return -ENOSYS;
 
216
                if (ret == EINVAL)
 
217
                        break;
 
218
                if (ret)
 
219
                        return fail("expected EINVAL, but got %d when enumerating buftype %d\n", ret, type);
 
220
                ret = check_0(fmtdesc.reserved, sizeof(fmtdesc.reserved));
 
221
                if (ret)
 
222
                        return fail("fmtdesc.reserved not zeroed\n");
 
223
                if (fmtdesc.index != f)
 
224
                        return fail("fmtdesc.index was modified\n");
 
225
                if (fmtdesc.type != type)
 
226
                        return fail("fmtdesc.type was modified\n");
 
227
                ret = check_ustring(fmtdesc.description, sizeof(fmtdesc.description));
 
228
                if (ret)
 
229
                        return fail("fmtdesc.description not set\n");
 
230
                if (!fmtdesc.pixelformat)
 
231
                        return fail("fmtdesc.pixelformat not set\n");
 
232
                if (!wrapper && (fmtdesc.flags & V4L2_FMT_FLAG_EMULATED))
 
233
                        return fail("drivers must never set the emulated flag\n");
 
234
                if (fmtdesc.flags & ~(V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_EMULATED))
 
235
                        return fail("unknown flag %08x returned\n", fmtdesc.flags);
 
236
                ret = testEnumFrameSizes(node, fmtdesc.pixelformat);
 
237
                if (ret > 0)
 
238
                        return ret;
 
239
                if (ret == 0 && !(node->caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)))
 
240
                        return fail("found framesizes when no video capture is supported\n");
 
241
                f++;
 
242
                if (type == V4L2_BUF_TYPE_PRIVATE)
 
243
                        continue;
 
244
                // Update array in v4l2-compliance.h if new buffer types are added
 
245
                assert(type <= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 
246
                if (set.find(fmtdesc.pixelformat) != set.end())
 
247
                        return fail("duplicate format %08x\n", fmtdesc.pixelformat);
 
248
                set.insert(fmtdesc.pixelformat);
 
249
        }
 
250
        info("found %d formats for buftype %d\n", f, type);
 
251
        return 0;
 
252
}
 
253
 
 
254
int testEnumFormats(struct node *node)
 
255
{
 
256
        static const __u32 buftype2cap[] = {
 
257
                0,
 
258
                V4L2_CAP_VIDEO_CAPTURE,
 
259
                V4L2_CAP_VIDEO_OUTPUT,
 
260
                V4L2_CAP_VIDEO_OVERLAY,
 
261
                V4L2_CAP_VBI_CAPTURE,
 
262
                V4L2_CAP_VBI_OUTPUT,
 
263
                V4L2_CAP_SLICED_VBI_CAPTURE,
 
264
                V4L2_CAP_SLICED_VBI_OUTPUT,
 
265
                V4L2_CAP_VIDEO_OUTPUT_OVERLAY,
 
266
                V4L2_CAP_VIDEO_CAPTURE_MPLANE,
 
267
                V4L2_CAP_VIDEO_OUTPUT_MPLANE,
 
268
        };
 
269
        int type;
 
270
        int ret;
 
271
 
 
272
        for (type = 0; type <= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; type++) {
 
273
                ret = testEnumFormatsType(node, (enum v4l2_buf_type)type);
 
274
                if (ret > 0)
 
275
                        return ret;
 
276
                switch (type) {
 
277
                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 
278
                case V4L2_BUF_TYPE_VIDEO_OUTPUT:
 
279
                case V4L2_BUF_TYPE_VIDEO_OVERLAY:
 
280
                case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 
281
                case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
 
282
                        if (ret < 0 && (node->caps & buftype2cap[type]))
 
283
                                return fail("%s cap set, but no %s formats defined\n",
 
284
                                                buftype2s(type).c_str(), buftype2s(type).c_str());
 
285
                        if (!ret && !(node->caps & buftype2cap[type]))
 
286
                                return fail("%s cap not set, but %s formats defined\n",
 
287
                                                buftype2s(type).c_str(), buftype2s(type).c_str());
 
288
                        break;
 
289
                default:
 
290
                        if (!ret)
 
291
                                return fail("Buffer type %s not allowed!\n", buftype2s(type).c_str());
 
292
                        break;
 
293
                }
 
294
        }
 
295
 
 
296
        ret = testEnumFormatsType(node, V4L2_BUF_TYPE_PRIVATE);
 
297
        if (ret > 0)
 
298
                return ret;
 
299
        if (!ret)
 
300
                warn("Buffer type PRIVATE allowed!\n");
 
301
                
 
302
        ret = testEnumFrameSizes(node, 0x20202020);
 
303
        if (ret >= 0)
 
304
                return fail("Accepted framesize for invalid format\n");
 
305
        ret = testEnumFrameIntervals(node, 0x20202020, 640, 480, false);
 
306
        if (ret >= 0)
 
307
                return fail("Accepted frameinterval for invalid format\n");
 
308
        return 0;
 
309
}
 
310
 
 
311
int testFBuf(struct node *node)
 
312
{
 
313
        struct v4l2_framebuffer fbuf;
 
314
        struct v4l2_pix_format &fmt = fbuf.fmt;
 
315
        __u32 caps;
 
316
        __u32 flags;
 
317
        int ret;
 
318
 
 
319
        memset(&fbuf, 0xff, sizeof(fbuf));
 
320
        fbuf.fmt.priv = 0;
 
321
        ret = doioctl(node, VIDIOC_G_FBUF, &fbuf);
 
322
        fail_on_test(ret == 0 && !(node->caps & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)));
 
323
        fail_on_test(ret == EINVAL && (node->caps & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)));
 
324
        if (ret == EINVAL)
 
325
                return -ENOSYS;
 
326
        if (ret)
 
327
                return fail("expected EINVAL, but got %d when getting framebuffer format\n", ret);
 
328
        node->fbuf_caps = caps = fbuf.capability;
 
329
        flags = fbuf.flags;
 
330
        if (node->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
 
331
                fail_on_test(!fbuf.base);
 
332
        if (flags & V4L2_FBUF_FLAG_CHROMAKEY)
 
333
                fail_on_test(!(caps & V4L2_FBUF_CAP_CHROMAKEY));
 
334
        if (flags & V4L2_FBUF_FLAG_LOCAL_ALPHA)
 
335
                fail_on_test(!(caps & V4L2_FBUF_CAP_LOCAL_ALPHA));
 
336
        if (flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA)
 
337
                fail_on_test(!(caps & V4L2_FBUF_CAP_GLOBAL_ALPHA));
 
338
        if (flags & V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)
 
339
                fail_on_test(!(caps & V4L2_FBUF_CAP_LOCAL_INV_ALPHA));
 
340
        if (flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)
 
341
                fail_on_test(!(caps & V4L2_FBUF_CAP_SRC_CHROMAKEY));
 
342
        fail_on_test(!fmt.width || !fmt.height);
 
343
        if (fmt.priv)
 
344
                warn("fbuf.fmt.priv is non-zero\n");
 
345
        /* Not yet: unclear what EXTERNOVERLAY means in a output overlay context
 
346
        if (caps & V4L2_FBUF_CAP_EXTERNOVERLAY) {
 
347
                fail_on_test(fmt.bytesperline);
 
348
                fail_on_test(fmt.sizeimage);
 
349
                fail_on_test(fbuf.base);
 
350
        }*/
 
351
        fail_on_test(fmt.bytesperline && fmt.bytesperline < fmt.width);
 
352
        fail_on_test(fmt.sizeimage && fmt.sizeimage < fmt.bytesperline * fmt.height);
 
353
        fail_on_test(!fmt.colorspace);
 
354
        return 0;
 
355
}
 
356
 
 
357
static int testFormatsType(struct node *node, enum v4l2_buf_type type)
 
358
{
 
359
        pixfmt_set &set = node->buftype_pixfmts[type];
 
360
        pixfmt_set *set_splane;
 
361
        struct v4l2_format fmt;
 
362
        struct v4l2_pix_format &pix = fmt.fmt.pix;
 
363
        struct v4l2_pix_format_mplane &pix_mp = fmt.fmt.pix_mp;
 
364
        struct v4l2_window &win = fmt.fmt.win;
 
365
        struct v4l2_vbi_format &vbi = fmt.fmt.vbi;
 
366
        struct v4l2_sliced_vbi_format &sliced = fmt.fmt.sliced;
 
367
        __u32 service_set = 0;
 
368
        unsigned cnt = 0;
 
369
        int ret;
 
370
        
 
371
        memset(&fmt, 0xff, sizeof(fmt));
 
372
        fmt.type = type;
 
373
        ret = doioctl(node, VIDIOC_G_FMT, &fmt);
 
374
        if (ret == EINVAL)
 
375
                return -ENOSYS;
 
376
        if (ret)
 
377
                return fail("expected EINVAL, but got %d when getting format for buftype %d\n", ret, type);
 
378
        fail_on_test(fmt.type != type);
 
379
        
 
380
        switch (type) {
 
381
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 
382
        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
 
383
                fail_on_test(!pix.width || !pix.height);
 
384
                if (set.find(pix.pixelformat) == set.end())
 
385
                        return fail("unknown pixelformat %08x for buftype %d\n",
 
386
                                        pix.pixelformat, type);
 
387
                fail_on_test(pix.bytesperline && pix.bytesperline < pix.width);
 
388
                fail_on_test(!pix.sizeimage);
 
389
                fail_on_test(!pix.colorspace);
 
390
                if (pix.priv)
 
391
                        warn("priv is non-zero!\n");
 
392
                break;
 
393
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 
394
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
 
395
                fail_on_test(!pix_mp.width || !pix_mp.height);
 
396
                set_splane = &node->buftype_pixfmts[type - 8];
 
397
                if (set.find(pix_mp.pixelformat) == set.end() &&
 
398
                    set_splane->find(pix_mp.pixelformat) == set_splane->end())
 
399
                        return fail("unknown pixelformat %08x for buftype %d\n",
 
400
                                        pix_mp.pixelformat, type);
 
401
                fail_on_test(!pix_mp.colorspace);
 
402
                ret = check_0(pix_mp.reserved, sizeof(pix_mp.reserved));
 
403
                if (ret)
 
404
                        return fail("pix_mp.reserved not zeroed\n");
 
405
                fail_on_test(pix_mp.num_planes == 0 || pix_mp.num_planes >= VIDEO_MAX_PLANES);
 
406
                for (int i = 0; i < pix_mp.num_planes; i++) {
 
407
                        struct v4l2_plane_pix_format &pfmt = pix_mp.plane_fmt[i];
 
408
 
 
409
                        ret = check_0(pfmt.reserved, sizeof(pfmt.reserved));
 
410
                        if (ret)
 
411
                                return fail("pix_mp.plane_fmt[%d].reserved not zeroed\n", i);
 
412
                        fail_on_test(!pfmt.sizeimage);
 
413
                        fail_on_test(pfmt.bytesperline && pfmt.bytesperline < pix_mp.width);
 
414
                }
 
415
                break;
 
416
        case V4L2_BUF_TYPE_VBI_CAPTURE:
 
417
        case V4L2_BUF_TYPE_VBI_OUTPUT:
 
418
                fail_on_test(!vbi.sampling_rate);
 
419
                fail_on_test(!vbi.samples_per_line);
 
420
                fail_on_test(vbi.sample_format != V4L2_PIX_FMT_GREY);
 
421
                fail_on_test(vbi.offset > vbi.samples_per_line);
 
422
                ret = check_0(vbi.reserved, sizeof(vbi.reserved));
 
423
                if (ret)
 
424
                        return fail("vbi.reserved not zeroed\n");
 
425
                fail_on_test(!vbi.count[0] || !vbi.count[1]);
 
426
                fail_on_test(vbi.flags & ~(V4L2_VBI_UNSYNC | V4L2_VBI_INTERLACED));
 
427
                if (vbi.flags & V4L2_VBI_INTERLACED)
 
428
                        fail_on_test(vbi.count[0] != vbi.count[1]);
 
429
                break;
 
430
        case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
 
431
        case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
 
432
                ret = check_0(sliced.reserved, sizeof(sliced.reserved));
 
433
                if (ret)
 
434
                        return fail("sliced.reserved not zeroed\n");
 
435
                fail_on_test(sliced.service_lines[0][0] || sliced.service_lines[1][0]);
 
436
                for (int f = 0; f < 2; f++) {
 
437
                        for (int i = 0; i < 24; i++) {
 
438
                                if (sliced.service_lines[f][i])
 
439
                                        cnt++;
 
440
                                service_set |= sliced.service_lines[f][i];
 
441
                        }
 
442
                }
 
443
                fail_on_test(sliced.io_size < sizeof(struct v4l2_sliced_vbi_data) * cnt);
 
444
                fail_on_test(sliced.service_set != service_set);
 
445
                break;
 
446
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
 
447
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
 
448
                fail_on_test(win.field != V4L2_FIELD_ANY &&
 
449
                             win.field != V4L2_FIELD_TOP &&
 
450
                             win.field != V4L2_FIELD_BOTTOM &&
 
451
                             win.field != V4L2_FIELD_INTERLACED);
 
452
                fail_on_test(win.clipcount && !(node->fbuf_caps & V4L2_FBUF_CAP_LIST_CLIPPING));
 
453
                for (struct v4l2_clip *clip = win.clips; clip; win.clipcount--) {
 
454
                        fail_on_test(clip == NULL);
 
455
                        clip = clip->next;
 
456
                }
 
457
                fail_on_test(win.clipcount);
 
458
                fail_on_test(win.chromakey && !(node->fbuf_caps & (V4L2_FBUF_CAP_CHROMAKEY | V4L2_FBUF_CAP_SRC_CHROMAKEY)));
 
459
                if (!(node->fbuf_caps & V4L2_FBUF_CAP_BITMAP_CLIPPING))
 
460
                        fail_on_test(win.bitmap);
 
461
                fail_on_test(win.global_alpha && !(node->fbuf_caps & V4L2_FBUF_CAP_GLOBAL_ALPHA));
 
462
                break;
 
463
        case V4L2_BUF_TYPE_PRIVATE:
 
464
                break;
 
465
        }
 
466
        return 0;
 
467
}
 
468
 
 
469
int testFormats(struct node *node)
 
470
{
 
471
        int type;
 
472
        int ret;
 
473
 
 
474
        for (type = 0; type <= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; type++) {
 
475
                ret = testFormatsType(node, (enum v4l2_buf_type)type);
 
476
 
 
477
                if (ret > 0)
 
478
                        return ret;
 
479
                if (ret && (node->caps & buftype2cap[type]))
 
480
                        return fail("%s cap set, but no %s formats defined\n",
 
481
                                        buftype2s(type).c_str(), buftype2s(type).c_str());
 
482
                if (!ret && !(node->caps & buftype2cap[type]))
 
483
                        return fail("%s cap not set, but %s formats defined\n",
 
484
                                        buftype2s(type).c_str(), buftype2s(type).c_str());
 
485
        }
 
486
 
 
487
        ret = testFormatsType(node, V4L2_BUF_TYPE_PRIVATE);
 
488
        if (ret > 0)
 
489
                return ret;
 
490
        if (!ret)
 
491
                warn("Buffer type PRIVATE allowed!\n");
 
492
        return 0;
 
493
}
 
494
 
 
495
static int testSlicedVBICapType(struct node *node, enum v4l2_buf_type type)
 
496
{
 
497
        struct v4l2_sliced_vbi_cap cap;
 
498
        bool sliced_type = (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE ||
 
499
                            type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT);
 
500
        __u32 service_set = 0;
 
501
        int ret;
 
502
 
 
503
        memset(&cap, 0xff, sizeof(cap));
 
504
        memset(&cap.reserved, 0, sizeof(cap.reserved));
 
505
        cap.type = type;
 
506
        ret = doioctl(node, VIDIOC_G_SLICED_VBI_CAP, &cap);
 
507
        fail_on_test(check_0(cap.reserved, sizeof(cap.reserved)));
 
508
        fail_on_test(cap.type != type);
 
509
        fail_on_test(ret && ret != EINVAL && sliced_type);
 
510
        if (ret == EINVAL) {
 
511
                fail_on_test(sliced_type && (node->caps & buftype2cap[type]));
 
512
                if (node->caps & (V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT))
 
513
                        return 0;
 
514
                return -ENOSYS;
 
515
        }
 
516
        if (ret)
 
517
                return fail("expected EINVAL, but got %d when getting sliced VBI caps buftype %d\n", ret, type);
 
518
        fail_on_test(!(node->caps & buftype2cap[type]));
 
519
 
 
520
        for (int f = 0; f < 2; f++)
 
521
                for (int i = 0; i < 24; i++)
 
522
                        service_set |= cap.service_lines[f][i];
 
523
        fail_on_test(cap.service_set != service_set);
 
524
        fail_on_test(cap.service_lines[0][0] || cap.service_lines[1][0]);
 
525
        return 0;
 
526
}
 
527
 
 
528
int testSlicedVBICap(struct node *node)
 
529
{
 
530
        int ret;
 
531
 
 
532
        ret = testSlicedVBICapType(node, V4L2_BUF_TYPE_SLICED_VBI_CAPTURE);
 
533
        if (ret)
 
534
                return ret;
 
535
        ret = testSlicedVBICapType(node, V4L2_BUF_TYPE_SLICED_VBI_OUTPUT);
 
536
        if (ret)
 
537
                return ret;
 
538
        return testSlicedVBICapType(node, V4L2_BUF_TYPE_VIDEO_CAPTURE);
 
539
}