1 /*
2 V4L2 API compliance input/output ioctl tests.
3
4 Copyright (C) 2011 Hans Verkuil <hverkuil@xs4all.nl>
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 <map>
22 #include <set>
23 #include <vector>
24
25 #include <sys/types.h>
26
27 #include "v4l2-compliance.h"
28
29 #define MAGIC 0x1eadbeef
30
checkEnumFreqBands(struct node * node,__u32 tuner,__u32 type,__u32 caps,__u32 rangelow,__u32 rangehigh)31 static int checkEnumFreqBands(struct node *node, __u32 tuner, __u32 type, __u32 caps,
32 __u32 rangelow, __u32 rangehigh)
33 {
34 const __u32 band_caps = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_1HZ;
35 __u32 caps_union = 0;
36 std::vector<v4l2_frequency_band> bands;
37 unsigned low = 0xffffffff;
38 unsigned high = 0;
39 unsigned i;
40
41 for (i = 0; ; i++) {
42 struct v4l2_frequency_band band;
43 int ret;
44
45 memset(band.reserved, 0, sizeof(band.reserved));
46 band.tuner = tuner;
47 band.type = type;
48 band.index = i;
49 ret = doioctl(node, VIDIOC_ENUM_FREQ_BANDS, &band);
50 if (ret == EINVAL && i)
51 return 0;
52 if (ret)
53 return fail("couldn't get freq band\n");
54 caps_union |= band.capability;
55 if ((caps & band_caps) != (band.capability & band_caps))
56 return fail("Inconsistent CAP_LOW/CAP_1HZ usage\n");
57 fail_on_test(band.rangelow == 0);
58 fail_on_test(band.rangehigh < band.rangelow);
59 fail_on_test(band.index != i);
60 fail_on_test(band.type != type);
61 fail_on_test(band.tuner != tuner);
62 fail_on_test((band.capability & V4L2_TUNER_CAP_FREQ_BANDS) == 0);
63 fail_on_test(check_0(band.reserved, sizeof(band.reserved)));
64 if (band.rangelow < low)
65 low = band.rangelow;
66 if (band.rangehigh > high)
67 high = band.rangehigh;
68 bands.push_back(band);
69 }
70 fail_on_test(caps_union != caps);
71 fail_on_test(low != rangelow);
72 fail_on_test(high != rangehigh);
73
74 // Check that the bands do not overlap or are adjacent
75 for (i = 0; i < bands.size(); i++)
76 for (unsigned j = 1; j < bands.size(); j++)
77 fail_on_test(bands[i].rangehigh + 1 >= bands[j].rangelow &&
78 bands[i].rangelow - 1 <= bands[j].rangehigh);
79 return 0;
80 }
81
checkTuner(struct node * node,const struct v4l2_tuner & tuner,unsigned t,v4l2_std_id std)82 static int checkTuner(struct node *node, const struct v4l2_tuner &tuner,
83 unsigned t, v4l2_std_id std)
84 {
85 bool valid_modes[5] = { true, false, false, false, false };
86 bool tv = node->is_video || node->is_vbi || node->is_meta;
87 bool hwseek_caps = tuner.capability & (V4L2_TUNER_CAP_HWSEEK_BOUNDED |
88 V4L2_TUNER_CAP_HWSEEK_WRAP | V4L2_TUNER_CAP_HWSEEK_PROG_LIM);
89 unsigned type = tv ? V4L2_TUNER_ANALOG_TV : V4L2_TUNER_RADIO;
90 __u32 audmode;
91
92 if (tuner.index != t)
93 return fail("invalid index\n");
94 if (check_ustring(tuner.name, sizeof(tuner.name)))
95 return fail("invalid name\n");
96 if (check_0(tuner.reserved, sizeof(tuner.reserved)))
97 return fail("non-zero reserved fields\n");
98 if (node->is_sdr) {
99 fail_on_test(tuner.type != V4L2_TUNER_SDR && tuner.type != V4L2_TUNER_RF);
100 } else if (tuner.type != type) {
101 return fail("invalid tuner type %d\n", tuner.type);
102 }
103 if (tv && (tuner.capability & V4L2_TUNER_CAP_RDS))
104 return fail("RDS for TV tuner?\n");
105 if (!tv && (tuner.capability & (V4L2_TUNER_CAP_NORM |
106 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2)))
107 return fail("TV capabilities for radio tuner?\n");
108 if (tv && (tuner.capability & (V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_1HZ)))
109 return fail("did not expect to see V4L2_TUNER_CAP_LOW/1HZ set for a tv tuner\n");
110 if (node->is_radio && !(tuner.capability & V4L2_TUNER_CAP_LOW))
111 return fail("V4L2_TUNER_CAP_LOW was not set for a radio tuner\n");
112 fail_on_test((tuner.capability & V4L2_TUNER_CAP_LOW) &&
113 (tuner.capability & V4L2_TUNER_CAP_1HZ));
114 if (node->is_sdr)
115 fail_on_test(!(V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_1HZ));
116 fail_on_test(!(tuner.capability & V4L2_TUNER_CAP_FREQ_BANDS));
117 fail_on_test(!(node->g_caps() & V4L2_CAP_HW_FREQ_SEEK) && hwseek_caps);
118 fail_on_test((node->g_caps() & V4L2_CAP_HW_FREQ_SEEK) &&
119 !(tuner.capability & (V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP)));
120 if (tuner.rangelow > tuner.rangehigh)
121 return fail("rangelow > rangehigh\n");
122 if (tuner.rangelow == 0 || tuner.rangehigh == 0xffffffff)
123 return fail("invalid rangelow or rangehigh\n");
124 if (!(tuner.capability & V4L2_TUNER_CAP_STEREO) &&
125 (tuner.rxsubchans & V4L2_TUNER_SUB_STEREO))
126 return fail("stereo subchan, but no stereo caps?\n");
127 if (!(tuner.capability & V4L2_TUNER_CAP_LANG1) &&
128 (tuner.rxsubchans & V4L2_TUNER_SUB_LANG1))
129 return fail("lang1 subchan, but no lang1 caps?\n");
130 if (!(tuner.capability & V4L2_TUNER_CAP_LANG2) &&
131 (tuner.rxsubchans & V4L2_TUNER_SUB_LANG2))
132 return fail("lang2 subchan, but no lang2 caps?\n");
133 if (!(tuner.capability & V4L2_TUNER_CAP_RDS) &&
134 (tuner.rxsubchans & V4L2_TUNER_SUB_RDS))
135 return fail("RDS subchan, but no RDS caps?\n");
136 bool have_rds = tuner.capability & V4L2_TUNER_CAP_RDS;
137 bool have_rds_method = tuner.capability &
138 (V4L2_TUNER_CAP_RDS_BLOCK_IO | V4L2_TUNER_CAP_RDS_CONTROLS);
139 if (have_rds ^ have_rds_method)
140 return fail("V4L2_TUNER_CAP_RDS is set, but not V4L2_TUNER_CAP_RDS_* or vice versa\n");
141 fail_on_test(node->is_sdr && have_rds);
142 if ((tuner.capability & V4L2_TUNER_CAP_RDS_BLOCK_IO) &&
143 !(node->g_caps() & V4L2_CAP_READWRITE))
144 return fail("V4L2_TUNER_CAP_RDS_BLOCK_IO is set, but not V4L2_CAP_READWRITE\n");
145 if (node->is_radio && !(tuner.capability & V4L2_TUNER_CAP_RDS_BLOCK_IO) &&
146 (node->g_caps() & V4L2_CAP_READWRITE))
147 return fail("V4L2_TUNER_CAP_RDS_BLOCK_IO is not set, but V4L2_CAP_READWRITE is\n");
148 if (std == V4L2_STD_NTSC_M && (tuner.rxsubchans & V4L2_TUNER_SUB_LANG1))
149 return fail("LANG1 subchan, but NTSC-M standard\n");
150 if (tuner.audmode > V4L2_TUNER_MODE_LANG1_LANG2)
151 return fail("invalid audio mode\n");
152 if (!tv && tuner.audmode > V4L2_TUNER_MODE_STEREO)
153 return fail("invalid audio mode for radio device\n");
154 if (tuner.signal > 65535)
155 return fail("signal too large\n");
156 if (tuner.capability & V4L2_TUNER_CAP_STEREO)
157 valid_modes[V4L2_TUNER_MODE_STEREO] = true;
158 if (tuner.capability & V4L2_TUNER_CAP_LANG1)
159 valid_modes[V4L2_TUNER_MODE_LANG1] = true;
160 if (tuner.capability & V4L2_TUNER_CAP_LANG2) {
161 valid_modes[V4L2_TUNER_MODE_LANG2] = true;
162 valid_modes[V4L2_TUNER_MODE_LANG1_LANG2] = true;
163 }
164 for (audmode = 0; audmode < 5; audmode++) {
165 struct v4l2_tuner tun = { 0 };
166
167 tun.index = tuner.index;
168 tun.audmode = audmode;
169 if (doioctl(node, VIDIOC_S_TUNER, &tun))
170 return fail("cannot set audmode %d\n", audmode);
171 if (doioctl(node, VIDIOC_G_TUNER, &tun))
172 fail("failure to get new tuner audmode\n");
173 if (tun.audmode > V4L2_TUNER_MODE_LANG1_LANG2)
174 return fail("invalid new audmode\n");
175 if (!valid_modes[tun.audmode])
176 return fail("accepted invalid audmode %d\n", audmode);
177 }
178 return checkEnumFreqBands(node, tuner.index, tuner.type, tuner.capability,
179 tuner.rangelow, tuner.rangehigh);
180 }
181
testTuner(struct node * node)182 int testTuner(struct node *node)
183 {
184 struct v4l2_tuner tuner;
185 v4l2_std_id std;
186 unsigned t = 0;
187 bool has_rds = false;
188 int ret;
189
190 if (doioctl(node, VIDIOC_G_STD, &std))
191 std = 0;
192
193 for (;;) {
194 memset(&tuner, 0xff, sizeof(tuner));
195 memset(tuner.reserved, 0, sizeof(tuner.reserved));
196 tuner.index = t;
197 ret = doioctl(node, VIDIOC_G_TUNER, &tuner);
198 if (ret == ENOTTY)
199 return ret;
200 if (ret == EINVAL)
201 break;
202 if (ret)
203 return fail("couldn't get tuner %d\n", t);
204 if (checkTuner(node, tuner, t, std))
205 return fail("invalid tuner %d\n", t);
206 t++;
207 node->tuners++;
208 if (tuner.capability & V4L2_TUNER_CAP_RDS)
209 has_rds = true;
210 }
211 memset(&tuner, 0, sizeof(tuner));
212 tuner.index = t;
213 if (doioctl(node, VIDIOC_S_TUNER, &tuner) != EINVAL)
214 return fail("could set invalid tuner %d\n", t);
215 if (node->tuners && !(node->g_caps() & V4L2_CAP_TUNER))
216 return fail("tuners found, but no tuner capability set\n");
217 if (!node->tuners && (node->g_caps() & V4L2_CAP_TUNER))
218 return fail("no tuners found, but tuner capability set\n");
219 if (has_rds && !(node->g_caps() & V4L2_CAP_RDS_CAPTURE))
220 return fail("RDS tuner capability, but no RDS capture capability?\n");
221 if (!has_rds && (node->g_caps() & V4L2_CAP_RDS_CAPTURE))
222 return fail("No RDS tuner capability, but RDS capture capability?\n");
223 return 0;
224 }
225
testTunerFreq(struct node * node)226 int testTunerFreq(struct node *node)
227 {
228 struct v4l2_frequency freq = { 0 };
229 enum v4l2_tuner_type last_type = V4L2_TUNER_ANALOG_TV;
230 unsigned t;
231 int ret;
232
233 for (t = 0; t < node->tuners; t++) {
234 struct v4l2_tuner tuner = { 0 };
235
236 tuner.index = t;
237 ret = doioctl(node, VIDIOC_G_TUNER, &tuner);
238 if (ret)
239 return fail("could not get tuner %d\n", t);
240 last_type = static_cast<enum v4l2_tuner_type>(tuner.type);
241 memset(&freq, 0, sizeof(freq));
242 freq.tuner = t;
243 ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
244 if (ret)
245 return fail("could not get frequency for tuner %d\n", t);
246 if (check_0(freq.reserved, sizeof(freq.reserved)))
247 return fail("reserved was not zeroed\n");
248 if (freq.type != V4L2_TUNER_RADIO && freq.type != V4L2_TUNER_ANALOG_TV &&
249 freq.type != V4L2_TUNER_SDR && freq.type != V4L2_TUNER_RF)
250 return fail("returned invalid tuner type %d\n", freq.type);
251 if (freq.type == V4L2_TUNER_RADIO && !(node->g_caps() & V4L2_CAP_RADIO))
252 return fail("radio tuner found but no radio capability set\n");
253 if ((freq.type == V4L2_TUNER_SDR || freq.type == V4L2_TUNER_RF) &&
254 !(node->g_caps() & V4L2_CAP_SDR_CAPTURE))
255 return fail("sdr tuner found but no sdr capture capability set\n");
256 if (freq.type != tuner.type)
257 return fail("frequency tuner type and tuner type mismatch\n");
258 if (freq.tuner != t)
259 return fail("frequency tuner field changed!\n");
260 if (freq.frequency == 0)
261 return fail("frequency not set\n");
262 if (freq.frequency < tuner.rangelow || freq.frequency > tuner.rangehigh)
263 warn("returned tuner %d frequency out of range (%d not in [%d...%d])\n",
264 t, freq.frequency, tuner.rangelow, tuner.rangehigh);
265
266 freq.type = static_cast<enum v4l2_tuner_type>(0);
267 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
268 if (ret != EINVAL)
269 return fail("did not return EINVAL when passed tuner type 0\n");
270 freq.type = tuner.type;
271 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
272 if (ret)
273 return fail("could not set current frequency\n");
274 freq.frequency = tuner.rangelow;
275 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
276 if (ret)
277 return fail("could not set rangelow frequency\n");
278 freq.frequency = tuner.rangehigh;
279 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
280 if (ret)
281 return fail("could not set rangehigh frequency\n");
282 freq.frequency = tuner.rangelow - 1;
283 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
284 if (ret)
285 return fail("could not set rangelow-1 frequency\n");
286 ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
287 if (ret || freq.frequency != tuner.rangelow)
288 return fail("frequency rangelow-1 wasn't mapped to rangelow\n");
289 freq.frequency = tuner.rangehigh + 1;
290 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
291 if (ret)
292 return fail("could not set rangehigh+1 frequency\n");
293 ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
294 if (ret || freq.frequency != tuner.rangehigh)
295 return fail("frequency rangehigh+1 wasn't mapped to rangehigh\n");
296
297 for (unsigned i = 0; ; i++) {
298 struct v4l2_frequency_band band;
299
300 memset(band.reserved, 0, sizeof(band.reserved));
301 band.tuner = t;
302 band.type = tuner.type;
303 band.index = i;
304 ret = doioctl(node, VIDIOC_ENUM_FREQ_BANDS, &band);
305 fail_on_test(i == 0 && ret);
306 if (ret == EINVAL)
307 break;
308 fail_on_test(ret);
309
310 freq.frequency = band.rangelow;
311 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
312 if (ret)
313 return fail("could not set rangelow frequency band\n");
314 freq.frequency = band.rangehigh;
315 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
316 if (ret)
317 return fail("could not set rangehigh frequency band\n");
318 freq.frequency = band.rangelow - 1;
319 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
320 if (ret)
321 return fail("could not set rangelow-1 frequency band\n");
322 ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
323 if (ret || freq.frequency != band.rangelow)
324 return fail("frequency band rangelow-1 wasn't mapped to rangelow\n");
325 freq.frequency = band.rangehigh + 1;
326 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
327 if (ret)
328 return fail("could not set rangehigh+1 frequency band\n");
329 ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
330 if (ret || freq.frequency != band.rangehigh)
331 return fail("frequency band rangehigh+1 wasn't mapped to rangehigh\n");
332 }
333 }
334
335 /* If this is a modulator device, then skip the remaining tests */
336 if (node->g_caps() & V4L2_CAP_MODULATOR)
337 return 0;
338
339 freq.tuner = t;
340 ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
341 if (ret != EINVAL && ret != ENOTTY)
342 return fail("could get frequency for invalid tuner %d\n", t);
343 freq.tuner = t;
344 freq.type = last_type;
345 // TV: 400 Mhz Radio: 100 MHz
346 freq.frequency = last_type == V4L2_TUNER_ANALOG_TV ? 6400 : 1600000;
347 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
348 if (ret != EINVAL && ret != ENOTTY)
349 return fail("could set frequency for invalid tuner %d\n", t);
350 return node->tuners ? 0 : ENOTTY;
351 }
352
testTunerHwSeek(struct node * node)353 int testTunerHwSeek(struct node *node)
354 {
355 struct v4l2_hw_freq_seek seek;
356 unsigned t;
357 int ret;
358
359 for (t = 0; t < node->tuners; t++) {
360 struct v4l2_tuner tuner = { 0 };
361
362 tuner.index = t;
363 ret = doioctl(node, VIDIOC_G_TUNER, &tuner);
364 if (ret)
365 return fail("could not get tuner %d\n", t);
366
367 memset(&seek, 0, sizeof(seek));
368 seek.tuner = t;
369 seek.type = V4L2_TUNER_RADIO;
370 ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
371 if (!(node->g_caps() & V4L2_CAP_HW_FREQ_SEEK) && ret != ENOTTY)
372 return fail("hw seek supported but capability not set\n");
373 if (!node->is_radio && ret != ENOTTY)
374 return fail("hw seek supported on a non-radio node?!\n");
375 if (!node->is_radio || !(node->g_caps() & V4L2_CAP_HW_FREQ_SEEK))
376 return ENOTTY;
377 seek.type = V4L2_TUNER_ANALOG_TV;
378 ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
379 if (ret != EINVAL)
380 return fail("hw seek accepted TV tuner\n");
381 seek.type = V4L2_TUNER_RADIO;
382 seek.seek_upward = 1;
383 ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
384 if (ret == EINVAL && (tuner.capability & V4L2_TUNER_CAP_HWSEEK_BOUNDED))
385 return fail("hw bounded seek failed\n");
386 if (ret && ret != EINVAL && ret != ENODATA)
387 return fail("hw bounded seek failed with error %d\n", ret);
388 seek.wrap_around = 1;
389 ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
390 if (ret == EINVAL && (tuner.capability & V4L2_TUNER_CAP_HWSEEK_WRAP))
391 return fail("hw wrapped seek failed\n");
392 if (ret && ret != EINVAL && ret != ENODATA)
393 return fail("hw wrapped seek failed with error %d\n", ret);
394 if (check_0(seek.reserved, sizeof(seek.reserved)))
395 return fail("non-zero reserved fields\n");
396 }
397 memset(&seek, 0, sizeof(seek));
398 seek.tuner = node->tuners;
399 seek.type = V4L2_TUNER_RADIO;
400 ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
401 if (ret != EINVAL && ret != ENOTTY)
402 return fail("hw seek for invalid tuner didn't return EINVAL or ENOTTY\n");
403 return ret == ENOTTY ? ret : 0;
404 }
405
checkInput(struct node * node,const struct v4l2_input & descr,unsigned i)406 static int checkInput(struct node *node, const struct v4l2_input &descr, unsigned i)
407 {
408 __u32 mask = (1 << node->audio_inputs) - 1;
409 struct v4l2_selection sel;
410
411 if (descr.index != i)
412 return fail("invalid index\n");
413 if (check_ustring(descr.name, sizeof(descr.name)))
414 return fail("invalid name\n");
415 if (descr.type != V4L2_INPUT_TYPE_TUNER &&
416 descr.type != V4L2_INPUT_TYPE_CAMERA &&
417 descr.type != V4L2_INPUT_TYPE_TOUCH)
418 return fail("invalid type\n");
419 if (descr.type == V4L2_INPUT_TYPE_CAMERA && descr.tuner)
420 return fail("invalid tuner\n");
421 if (descr.type == V4L2_INPUT_TYPE_TUNER && node->tuners == 0)
422 return fail("no tuners found for tuner input\n");
423 if (!(descr.capabilities & V4L2_IN_CAP_STD) && descr.std)
424 return fail("invalid std\n");
425 if ((descr.capabilities & V4L2_IN_CAP_STD) && !descr.std)
426 return fail("std == 0\n");
427 memset(&sel, 0, sizeof(sel));
428 sel.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
429 sel.target = V4L2_SEL_TGT_NATIVE_SIZE;
430 if (descr.capabilities & V4L2_IN_CAP_NATIVE_SIZE) {
431 fail_on_test(doioctl(node, VIDIOC_G_SELECTION, &sel));
432 fail_on_test(doioctl(node, VIDIOC_S_SELECTION, &sel));
433 } else if (!doioctl(node, VIDIOC_G_SELECTION, &sel)) {
434 fail_on_test(!doioctl(node, VIDIOC_S_SELECTION, &sel));
435 }
436 if (descr.capabilities & ~0x7)
437 return fail("invalid capabilities\n");
438 if (check_0(descr.reserved, sizeof(descr.reserved)))
439 return fail("non-zero reserved fields\n");
440 if (descr.status & ~0x07070337)
441 return fail("invalid status\n");
442 // These bits were for Digital TV, but Digital TV uses the
443 // DVB API and no longer V4L2.
444 if (descr.status & (V4L2_IN_ST_NO_EQU | V4L2_IN_ST_NO_CARRIER |
445 V4L2_IN_ST_NO_ACCESS))
446 return fail("use of deprecated Digital TV status bits\n");
447 if (descr.audioset & ~mask)
448 return fail("invalid audioset\n");
449 if (descr.tuner && descr.tuner >= node->tuners)
450 return fail("invalid tuner\n");
451 return 0;
452 }
453
roundup(unsigned v,unsigned mult)454 static unsigned roundup(unsigned v, unsigned mult)
455 {
456 return mult * ((v + mult - 1) / mult);
457 }
458
checkVividPixelArray(struct node * node)459 static int checkVividPixelArray(struct node *node)
460 {
461 struct v4l2_query_ext_ctrl qextctrl = {
462 .id = VIVID_CID_U8_PIXEL_ARRAY
463 };
464 cv4l_fmt fmt;
465
466 fail_on_test(node->query_ext_ctrl(qextctrl));
467 fail_on_test(node->g_fmt(fmt));
468 fail_on_test(qextctrl.nr_of_dims != 2);
469 fail_on_test(qextctrl.dims[0] != roundup(fmt.g_width(), PIXEL_ARRAY_DIV));
470 fail_on_test(qextctrl.dims[1] != roundup(fmt.g_height(), PIXEL_ARRAY_DIV));
471 fail_on_test(qextctrl.minimum == qextctrl.default_value);
472
473 struct v4l2_ext_control ctrl = {
474 .id = VIVID_CID_U8_PIXEL_ARRAY
475 };
476 struct v4l2_ext_controls ctrls = {};
477
478 ctrl.size = qextctrl.elems * qextctrl.elem_size;
479 ctrl.p_u8 = new unsigned char[ctrl.size];
480 ctrls.count = 1;
481 ctrls.controls = &ctrl;
482 fail_on_test(node->g_ext_ctrls(ctrls));
483 for (unsigned i = 0; i < qextctrl.elems; i++) {
484 fail_on_test(ctrl.p_u8[i] != qextctrl.default_value);
485 ctrl.p_u8[i] = qextctrl.minimum;
486 }
487 fail_on_test(node->s_ext_ctrls(ctrls));
488 fail_on_test(node->g_ext_ctrls(ctrls));
489 for (unsigned i = 0; i < qextctrl.elems; i++) {
490 fail_on_test(ctrl.p_u8[i] != qextctrl.minimum);
491 }
492 delete [] ctrl.p_u8;
493 return 0;
494 }
495
testInput(struct node * node)496 int testInput(struct node *node)
497 {
498 struct v4l2_input descr;
499 int cur_input = MAGIC;
500 int input;
501 int ret = doioctl(node, VIDIOC_G_INPUT, &cur_input);
502 int i = 0;
503
504 if (ret == ENOTTY) {
505 if (node->has_inputs) {
506 if (media_fd < 0)
507 return fail("G_INPUT not supported for a capture device\n");
508 node->has_inputs = false;
509 return ENOTTY;
510 }
511 descr.index = 0;
512 ret = doioctl(node, VIDIOC_ENUMINPUT, &descr);
513 if (ret != ENOTTY)
514 return fail("G_INPUT not supported, but ENUMINPUT is\n");
515 cur_input = 0;
516 ret = doioctl(node, VIDIOC_S_INPUT, &cur_input);
517 if (ret != ENOTTY)
518 return fail("G_INPUT not supported, but S_INPUT is\n");
519 return ENOTTY;
520 }
521 if (ret)
522 return fail("could not get current input\n");
523 if (cur_input == MAGIC)
524 return fail("VIDIOC_G_INPUT didn't fill in the input\n");
525 if (node->is_radio)
526 return fail("radio can't have input support\n");
527 if (is_vivid && cur_input == 0) {
528 // for vivid start off with a different input than the
529 // current one. This ensures that the checkVividPixelArray()
530 // call later succeeds since switching to input 0 will reset
531 // that control to the default values.
532 input = 1;
533 doioctl(node, VIDIOC_S_INPUT, &input);
534 }
535 for (;;) {
536 memset(&descr, 0xff, sizeof(descr));
537 descr.index = i;
538 ret = doioctl(node, VIDIOC_ENUMINPUT, &descr);
539 if (ret == EINVAL)
540 break;
541 if (ret)
542 return fail("could not enumerate input %d\n", i);
543 input = i;
544 if (doioctl(node, VIDIOC_S_INPUT, &input))
545 return fail("could not set input to %d\n", i);
546 if (input != i)
547 return fail("input set to %d, but becomes %d?!\n", i, input);
548 if (checkInput(node, descr, i))
549 return fail("invalid attributes for input %d\n", i);
550 if (is_vivid && node->is_video && checkVividPixelArray(node))
551 return fail("vivid pixel array control test failed\n");
552 node->inputs++;
553 i++;
554 }
555 input = i;
556 if (doioctl(node, VIDIOC_S_INPUT, &input) != EINVAL)
557 return fail("could set input to invalid input %d\n", i);
558 if (doioctl(node, VIDIOC_S_INPUT, &cur_input))
559 return fail("couldn't set input to the original input %d\n", cur_input);
560 if (node->inputs && !node->has_inputs)
561 return fail("inputs found, but no input capabilities set\n");
562 if (!node->inputs && node->has_inputs)
563 return fail("no inputs found, but input capabilities set\n");
564 fail_on_test(node->is_m2m && node->inputs > 1);
565 if (node->is_io_mc) {
566 fail_on_test(!node->is_video && !node->is_meta);
567 fail_on_test(node->inputs != 1);
568 }
569 return 0;
570 }
571
checkInputAudio(const struct v4l2_audio & descr,unsigned i)572 static int checkInputAudio(const struct v4l2_audio &descr, unsigned i)
573 {
574 if (descr.index != i)
575 return fail("invalid index\n");
576 if (check_ustring(descr.name, sizeof(descr.name)))
577 return fail("invalid name\n");
578 if (descr.capability & ~0x3)
579 return fail("invalid capabilities\n");
580 if (descr.mode != 0 && descr.mode != V4L2_AUDMODE_AVL)
581 return fail("invalid mode\n");
582 if (!(descr.capability & V4L2_AUDCAP_AVL) && descr.mode)
583 return fail("mode != 0\n");
584 if (check_0(descr.reserved, sizeof(descr.reserved)))
585 return fail("non-zero reserved fields\n");
586 return 0;
587 }
588
testEnumInputAudio(struct node * node)589 int testEnumInputAudio(struct node *node)
590 {
591 struct v4l2_audio input;
592 unsigned i = 0;
593 int ret;
594
595 for (;;) {
596 memset(&input, 0xff, sizeof(input));
597 input.index = i;
598
599 ret = doioctl(node, VIDIOC_ENUMAUDIO, &input);
600 if (ret == ENOTTY)
601 return ret;
602 if (ret == EINVAL)
603 break;
604 if (ret)
605 return fail("could not enumerate audio input %d\n", i);
606 if (checkInputAudio(input, i))
607 return fail("invalid attributes for audio input %d\n", i);
608 node->audio_inputs++;
609 i++;
610 }
611 if (node->audio_inputs && !(node->g_caps() & V4L2_CAP_AUDIO))
612 return fail("audio inputs reported, but no CAP_AUDIO set\n");
613 return 0;
614 }
615
checkInputAudioSet(struct node * node,__u32 audioset)616 static int checkInputAudioSet(struct node *node, __u32 audioset)
617 {
618 struct v4l2_audio input = { 0 };
619 unsigned i;
620 int ret;
621
622 ret = doioctl(node, VIDIOC_G_AUDIO, &input);
623 if (audioset == 0 && ret != ENOTTY && ret != EINVAL)
624 return fail("No audioset, but G_AUDIO did not return ENOTTY or EINVAL\n");
625 if (audioset) {
626 if (ret)
627 return fail("Audio inputs, but G_AUDIO returned an error\n");
628 if (input.index >= node->audio_inputs)
629 return fail("invalid current audio input %d\n", input.index);
630 if (checkInputAudio(input, input.index))
631 return fail("invalid attributes for audio input %d\n", input.index);
632 }
633
634 for (i = 0; i <= node->audio_inputs; i++) {
635 int valid = audioset & (1 << i);
636
637 memset(&input, 0xff, sizeof(input));
638 memset(input.reserved, 0, sizeof(input.reserved));
639 input.index = i;
640 input.mode = 0;
641 ret = doioctl(node, VIDIOC_S_AUDIO, &input);
642 if (!valid && ret != EINVAL && ret != ENOTTY)
643 return fail("can set invalid audio input %d\n", i);
644 if (valid && ret)
645 return fail("can't set valid audio input %d\n", i);
646 }
647 return 0;
648 }
649
testInputAudio(struct node * node)650 int testInputAudio(struct node *node)
651 {
652 struct v4l2_input vinput = { 0 };
653 unsigned i = 0;
654 int ret;
655
656 if (node->audio_inputs && node->inputs == 0)
657 return fail("audio inputs found but no video inputs?!\n");
658
659 for (i = 0; i < node->inputs; i++) {
660 ret = doioctl(node, VIDIOC_S_INPUT, &i);
661 if (ret)
662 return fail("could not select input %d\n", i);
663 vinput.index = i;
664 ret = doioctl(node, VIDIOC_ENUMINPUT, &vinput);
665 if (ret)
666 return fail("could not enumerate input %d\n", i);
667 if (checkInputAudioSet(node, vinput.audioset))
668 return fail("invalid audioset for input %d\n", i);
669 }
670 return node->audio_inputs ? 0 : ENOTTY;
671 }
672
checkModulator(struct node * node,const struct v4l2_modulator & mod,unsigned m)673 static int checkModulator(struct node *node, const struct v4l2_modulator &mod, unsigned m)
674 {
675 bool tv = !node->is_radio && !node->is_sdr;
676
677 if (mod.index != m)
678 return fail("invalid index\n");
679 if (check_ustring(mod.name, sizeof(mod.name)))
680 return fail("invalid name\n");
681 if (check_0(mod.reserved, sizeof(mod.reserved)))
682 return fail("non-zero reserved fields\n");
683 if (tv)
684 return fail("currently only radio/sdr modulators are supported\n");
685 if (node->is_sdr)
686 fail_on_test(mod.type != V4L2_TUNER_SDR && mod.type != V4L2_TUNER_RF);
687 else if (mod.type != V4L2_TUNER_RADIO)
688 return fail("invalid modulator type %d\n", mod.type);
689
690 if (!(mod.capability & (V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_1HZ)))
691 return fail("V4L2_TUNER_CAP_LOW/1HZ was not set for a radio modulator\n");
692 if (mod.capability & (V4L2_TUNER_CAP_NORM |
693 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2))
694 return fail("TV capabilities for radio modulator?\n");
695 fail_on_test(!(mod.capability & V4L2_TUNER_CAP_FREQ_BANDS));
696 if (mod.rangelow > mod.rangehigh)
697 return fail("rangelow > rangehigh\n");
698 if (mod.rangelow == 0 || mod.rangehigh == 0xffffffff)
699 return fail("invalid rangelow or rangehigh\n");
700 if (!(mod.capability & V4L2_TUNER_CAP_STEREO) &&
701 (mod.txsubchans & V4L2_TUNER_SUB_STEREO))
702 return fail("stereo subchan, but no stereo caps?\n");
703 if (!(mod.capability & V4L2_TUNER_CAP_LANG1) &&
704 (mod.txsubchans & V4L2_TUNER_SUB_LANG1))
705 return fail("lang1 subchan, but no lang1 caps?\n");
706 if (!(mod.capability & V4L2_TUNER_CAP_LANG2) &&
707 (mod.txsubchans & V4L2_TUNER_SUB_LANG2))
708 return fail("lang2 subchan, but no lang2 caps?\n");
709 if (!(mod.capability & V4L2_TUNER_CAP_RDS) &&
710 (mod.txsubchans & V4L2_TUNER_SUB_RDS))
711 return fail("RDS subchan, but no RDS caps?\n");
712 bool have_rds = mod.capability & V4L2_TUNER_CAP_RDS;
713 bool have_rds_method = mod.capability &
714 (V4L2_TUNER_CAP_RDS_BLOCK_IO | V4L2_TUNER_CAP_RDS_CONTROLS);
715 if (have_rds ^ have_rds_method)
716 return fail("V4L2_TUNER_CAP_RDS is set, but not V4L2_TUNER_CAP_RDS_* or vice versa\n");
717 if ((mod.capability & V4L2_TUNER_CAP_RDS_BLOCK_IO) &&
718 !(node->g_caps() & V4L2_CAP_READWRITE))
719 return fail("V4L2_TUNER_CAP_RDS_BLOCK_IO is set, but not V4L2_CAP_READWRITE\n");
720 if (!node->is_sdr && !(mod.capability & V4L2_TUNER_CAP_RDS_BLOCK_IO) &&
721 (node->g_caps() & V4L2_CAP_READWRITE))
722 return fail("V4L2_TUNER_CAP_RDS_BLOCK_IO is not set, but V4L2_CAP_READWRITE is\n");
723 return checkEnumFreqBands(node, mod.index, mod.type, mod.capability,
724 mod.rangelow, mod.rangehigh);
725 }
726
testModulator(struct node * node)727 int testModulator(struct node *node)
728 {
729 struct v4l2_modulator mod;
730 unsigned m = 0;
731 bool has_rds = false;
732 int ret;
733
734 for (;;) {
735 memset(&mod, 0xff, sizeof(mod));
736 memset(mod.reserved, 0, sizeof(mod.reserved));
737 mod.index = m;
738 ret = doioctl(node, VIDIOC_G_MODULATOR, &mod);
739 if (ret == ENOTTY)
740 return ret;
741 if (ret == EINVAL)
742 break;
743 if (ret)
744 return fail("couldn't get modulator %d\n", m);
745 if (checkModulator(node, mod, m))
746 return fail("invalid modulator %d\n", m);
747 if (doioctl(node, VIDIOC_S_MODULATOR, &mod))
748 return fail("cannot set modulator %d\n", m);
749 m++;
750 node->modulators++;
751 if (mod.capability & V4L2_TUNER_CAP_RDS)
752 has_rds = true;
753 }
754 memset(&mod, 0, sizeof(mod));
755 mod.index = m;
756 if (doioctl(node, VIDIOC_S_MODULATOR, &mod) != EINVAL)
757 return fail("could set invalid modulator %d\n", m);
758 if (node->modulators && !(node->g_caps() & V4L2_CAP_MODULATOR))
759 return fail("modulators found, but no modulator capability set\n");
760 if (!node->modulators && (node->g_caps() & V4L2_CAP_MODULATOR))
761 return fail("no modulators found, but modulator capability set\n");
762 if (has_rds && !(node->g_caps() & V4L2_CAP_RDS_OUTPUT))
763 return fail("RDS modulator capability, but no RDS output capability?\n");
764 if (!has_rds && (node->g_caps() & V4L2_CAP_RDS_OUTPUT))
765 return fail("No RDS modulator capability, but RDS output capability?\n");
766 return 0;
767 }
768
testModulatorFreq(struct node * node)769 int testModulatorFreq(struct node *node)
770 {
771 struct v4l2_frequency freq = { 0 };
772 unsigned m;
773 int ret;
774
775 for (m = 0; m < node->modulators; m++) {
776 struct v4l2_modulator modulator;
777
778 modulator.index = m;
779 memset(modulator.reserved, 0, sizeof(modulator.reserved));
780 ret = doioctl(node, VIDIOC_G_MODULATOR, &modulator);
781 if (ret)
782 return fail("could not get modulator %d\n", m);
783 memset(&freq, 0, sizeof(freq));
784 freq.tuner = m;
785 ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
786 if (ret)
787 return fail("could not get frequency for modulator %d\n", m);
788 if (check_0(freq.reserved, sizeof(freq.reserved)))
789 return fail("reserved was not zeroed\n");
790 if (freq.tuner != m)
791 return fail("frequency modulator field changed!\n");
792 if ((freq.type == V4L2_TUNER_SDR || freq.type == V4L2_TUNER_RF) &&
793 !(node->g_caps() & V4L2_CAP_SDR_OUTPUT))
794 return fail("sdr tuner found but no sdr output capability set\n");
795 if (freq.frequency == 0)
796 return fail("frequency not set\n");
797 if (freq.frequency < modulator.rangelow || freq.frequency > modulator.rangehigh)
798 warn("returned modulator %d frequency out of range (%d not in [%d...%d])\n",
799 m, freq.frequency, modulator.rangelow, modulator.rangehigh);
800
801 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
802 if (ret)
803 return fail("could not set current frequency\n");
804 freq.frequency = modulator.rangelow;
805 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
806 if (ret)
807 return fail("could not set rangelow frequency\n");
808 freq.frequency = modulator.rangehigh;
809 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
810 if (ret)
811 return fail("could not set rangehigh frequency\n");
812 freq.frequency = modulator.rangelow - 1;
813 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
814 if (ret)
815 return fail("could not set rangelow-1 frequency\n");
816 ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
817 if (ret || freq.frequency != modulator.rangelow)
818 return fail("frequency rangelow-1 wasn't mapped to rangelow\n");
819 freq.frequency = modulator.rangehigh + 1;
820 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
821 if (ret)
822 return fail("could not set rangehigh+1 frequency\n");
823 ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
824 if (ret || freq.frequency != modulator.rangehigh)
825 return fail("frequency rangehigh+1 wasn't mapped to rangehigh\n");
826 }
827
828 /* If this is a tuner device, then skip the remaining tests */
829 if (node->g_caps() & V4L2_CAP_TUNER)
830 return 0;
831
832 freq.tuner = m;
833 ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
834 if (ret != EINVAL && ret != ENOTTY)
835 return fail("could get frequency for invalid modulator %d\n", m);
836 freq.tuner = m;
837 // Radio: 100 MHz
838 freq.frequency = 1600000;
839 ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
840 if (ret != EINVAL && ret != ENOTTY)
841 return fail("could set frequency for invalid modulator %d\n", m);
842 return node->modulators ? 0 : ENOTTY;
843 }
844
checkOutput(struct node * node,const struct v4l2_output & descr,unsigned o)845 static int checkOutput(struct node *node, const struct v4l2_output &descr, unsigned o)
846 {
847 __u32 mask = (1 << node->audio_outputs) - 1;
848 struct v4l2_selection sel;
849
850 if (descr.index != o)
851 return fail("invalid index\n");
852 if (check_ustring(descr.name, sizeof(descr.name)))
853 return fail("invalid name\n");
854 if (descr.type != V4L2_OUTPUT_TYPE_MODULATOR && descr.type != V4L2_OUTPUT_TYPE_ANALOG &&
855 descr.type != V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY)
856 return fail("invalid type\n");
857 if (descr.type != V4L2_OUTPUT_TYPE_MODULATOR && descr.modulator)
858 return fail("invalid modulator\n");
859 if (descr.type == V4L2_OUTPUT_TYPE_MODULATOR && node->modulators == 0)
860 return fail("no modulators found for modulator output\n");
861 if (!(descr.capabilities & V4L2_OUT_CAP_STD) && descr.std)
862 return fail("invalid std\n");
863 if ((descr.capabilities & V4L2_OUT_CAP_STD) && !descr.std)
864 return fail("std == 0\n");
865 memset(&sel, 0, sizeof(sel));
866 sel.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
867 sel.target = V4L2_SEL_TGT_NATIVE_SIZE;
868 if (descr.capabilities & V4L2_OUT_CAP_NATIVE_SIZE) {
869 fail_on_test(doioctl(node, VIDIOC_G_SELECTION, &sel));
870 fail_on_test(doioctl(node, VIDIOC_S_SELECTION, &sel));
871 } else if (!doioctl(node, VIDIOC_G_SELECTION, &sel)) {
872 fail_on_test(!doioctl(node, VIDIOC_S_SELECTION, &sel));
873 }
874 if (descr.capabilities & ~0x7)
875 return fail("invalid capabilities\n");
876 if (check_0(descr.reserved, sizeof(descr.reserved)))
877 return fail("non-zero reserved fields\n");
878 if (descr.audioset & ~mask)
879 return fail("invalid audioset\n");
880 if (descr.modulator && descr.modulator >= node->modulators)
881 return fail("invalid modulator\n");
882 return 0;
883 }
884
testOutput(struct node * node)885 int testOutput(struct node *node)
886 {
887 struct v4l2_output descr;
888 int cur_output = MAGIC;
889 int output;
890 int ret = doioctl(node, VIDIOC_G_OUTPUT, &cur_output);
891 int o = 0;
892
893 if (ret == ENOTTY) {
894 if (node->has_outputs) {
895 if (media_fd < 0)
896 return fail("G_OUTPUT not supported for an output device\n");
897 node->has_outputs = false;
898 return ENOTTY;
899 }
900 descr.index = 0;
901 ret = doioctl(node, VIDIOC_ENUMOUTPUT, &descr);
902 if (ret != ENOTTY)
903 return fail("G_OUTPUT not supported, but ENUMOUTPUT is\n");
904 output = 0;
905 ret = doioctl(node, VIDIOC_S_OUTPUT, &output);
906 if (ret != ENOTTY)
907 return fail("G_OUTPUT not supported, but S_OUTPUT is\n");
908 }
909 if (ret)
910 return ret;
911 if (cur_output == MAGIC)
912 return fail("VIDIOC_G_OUTPUT didn't fill in the output\n");
913 for (;;) {
914 memset(&descr, 0xff, sizeof(descr));
915 descr.index = o;
916 ret = doioctl(node, VIDIOC_ENUMOUTPUT, &descr);
917 if (ret)
918 break;
919 output = o;
920 if (doioctl(node, VIDIOC_S_OUTPUT, &output))
921 return fail("could not set output to %d\n", o);
922 if (output != o)
923 return fail("output set to %d, but becomes %d?!\n", o, output);
924 if (checkOutput(node, descr, o))
925 return fail("invalid attributes for output %d\n", o);
926 node->outputs++;
927 o++;
928 }
929 output = o;
930 if (doioctl(node, VIDIOC_S_OUTPUT, &output) != EINVAL)
931 return fail("could set output to invalid output %d\n", o);
932 if (doioctl(node, VIDIOC_S_OUTPUT, &cur_output))
933 return fail("couldn't set output to the original output %d\n", cur_output);
934 if (node->outputs && !node->has_outputs)
935 return fail("outputs found, but no output capabilities set\n");
936 if (!node->outputs && node->has_outputs)
937 return fail("no outputs found, but output capabilities set\n");
938 fail_on_test(node->is_m2m && node->outputs > 1);
939 if (node->is_io_mc) {
940 fail_on_test(!node->is_video && !node->is_meta);
941 fail_on_test(node->outputs != 1);
942 }
943 return 0;
944 }
945
checkOutputAudio(const struct v4l2_audioout & descr,unsigned o)946 static int checkOutputAudio(const struct v4l2_audioout &descr, unsigned o)
947 {
948 if (descr.index != o)
949 return fail("invalid index\n");
950 if (check_ustring(descr.name, sizeof(descr.name)))
951 return fail("invalid name\n");
952 if (descr.capability)
953 return fail("invalid capabilities\n");
954 if (descr.mode)
955 return fail("invalid mode\n");
956 if (check_0(descr.reserved, sizeof(descr.reserved)))
957 return fail("non-zero reserved fields\n");
958 return 0;
959 }
960
testEnumOutputAudio(struct node * node)961 int testEnumOutputAudio(struct node *node)
962 {
963 struct v4l2_audioout output;
964 unsigned o = 0;
965 int ret;
966
967 for (;;) {
968 memset(&output, 0xff, sizeof(output));
969 output.index = o;
970
971 ret = doioctl(node, VIDIOC_ENUMAUDOUT, &output);
972 if (ret == ENOTTY)
973 return ENOTTY;
974 if (ret == EINVAL)
975 break;
976 if (ret)
977 return fail("could not enumerate audio output %d\n", o);
978 if (checkOutputAudio(output, o))
979 return fail("invalid attributes for audio output %d\n", o);
980 node->audio_outputs++;
981 o++;
982 }
983
984 if (node->audio_outputs && !(node->g_caps() & V4L2_CAP_AUDIO))
985 return fail("audio outputs reported, but no CAP_AUDIO set\n");
986 return 0;
987 }
988
checkOutputAudioSet(struct node * node,__u32 audioset)989 static int checkOutputAudioSet(struct node *node, __u32 audioset)
990 {
991 struct v4l2_audioout output;
992 unsigned i;
993 int ret;
994
995 memset(output.reserved, 0, sizeof(output.reserved));
996 ret = doioctl(node, VIDIOC_G_AUDOUT, &output);
997 if (audioset == 0 && ret != EINVAL && ret != ENOTTY)
998 return fail("No audio outputs, but G_AUDOUT did not return EINVAL or ENOTTY\n");
999 if (audioset) {
1000 if (ret)
1001 return fail("Audio outputs, but G_AUDOUT returned an error\n");
1002 if (output.index >= node->audio_outputs)
1003 return fail("invalid current audio output %d\n", output.index);
1004 if (checkOutputAudio(output, output.index))
1005 return fail("invalid attributes for audio output %d\n", output.index);
1006 }
1007
1008 for (i = 0; i <= node->audio_outputs; i++) {
1009 int valid = audioset & (1 << i);
1010
1011 memset(&output, 0xff, sizeof(output));
1012 memset(output.reserved, 0, sizeof(output.reserved));
1013 output.index = i;
1014 output.mode = 0;
1015 ret = doioctl(node, VIDIOC_S_AUDOUT, &output);
1016 if (!valid && ret != EINVAL && ret != ENOTTY)
1017 return fail("can set invalid audio output %d\n", i);
1018 if (valid && ret)
1019 return fail("can't set valid audio output %d\n", i);
1020 }
1021 return 0;
1022 }
1023
testOutputAudio(struct node * node)1024 int testOutputAudio(struct node *node)
1025 {
1026 struct v4l2_output voutput;
1027 unsigned o = 0;
1028 int ret;
1029
1030 if (node->audio_outputs && node->outputs == 0)
1031 return fail("audio outputs found but no video outputs?!\n");
1032
1033 for (o = 0; o < node->outputs; o++) {
1034 ret = doioctl(node, VIDIOC_S_OUTPUT, &o);
1035 if (ret)
1036 return fail("could not select output %d\n", o);
1037 voutput.index = o;
1038 ret = doioctl(node, VIDIOC_ENUMOUTPUT, &voutput);
1039 if (ret)
1040 return fail("could not enumerate output %d\n", o);
1041 if (checkOutputAudioSet(node, voutput.audioset))
1042 return fail("invalid audioset for output %d\n", o);
1043 }
1044
1045 if (node->audio_outputs == 0 && node->audio_inputs == 0 && (node->g_caps() & V4L2_CAP_AUDIO))
1046 return fail("no audio inputs or outputs reported, but CAP_AUDIO set\n");
1047 return node->audio_outputs ? 0 : ENOTTY;
1048 }
1049