• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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