blob: e3c607cffc7a0b226967bad42392c7c87b699a1d [file] [log] [blame]
Philippe De Muyter0cc96142014-11-03 21:27:40 +01001/*
2 * Copyright (c) 2014 Philippe De Muyter <phdm@macqel.be>
3 * Copyright (c) 2014 William Manley <will@williammanley.net>
4 * Copyright (c) 2011 Peter Zotov <whitequark@whitequark.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "defs.h"
31
32#include <stdint.h>
33#include <sys/ioctl.h>
34#include <linux/videodev2.h>
35/* some historical constants */
36#ifndef V4L2_CID_HCENTER
37#define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
38#endif
39#ifndef V4L2_CID_VCENTER
40#define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
41#endif
42#ifndef V4L2_CID_BAND_STOP_FILTER
43#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
44#endif
45
46#include "xlat/v4l2_device_capabilities_flags.h"
47#include "xlat/v4l2_buf_types.h"
48#include "xlat/v4l2_buf_flags.h"
49#include "xlat/v4l2_framesize_types.h"
50#include "xlat/v4l2_frameinterval_types.h"
51#include "xlat/v4l2_fields.h"
52#include "xlat/v4l2_colorspaces.h"
53#include "xlat/v4l2_format_description_flags.h"
54#include "xlat/v4l2_memories.h"
55#include "xlat/v4l2_control_ids.h"
56#include "xlat/v4l2_control_types.h"
57#include "xlat/v4l2_control_flags.h"
58#include "xlat/v4l2_control_classes.h"
59#include "xlat/v4l2_streaming_capabilities.h"
60#include "xlat/v4l2_capture_modes.h"
61#include "xlat/v4l2_input_types.h"
62
63#define FMT_FRACT "%u/%u"
64#define ARGS_FRACT(x) ((x).numerator), ((x).denominator)
65
66#define FMT_RECT "{left=%i, top=%i, width=%i, height=%i}"
67#define ARGS_RECT(x) (x).left, (x).top, (x).width, (x).height
68
69static void print_pixelformat(uint32_t fourcc)
70{
71#if WORDS_BIGENDIAN
72 fourcc = htole32(fourcc);
73#endif
74 tprintf("%.4s", (char*)&fourcc);
75}
76
77static void print_v4l2_format_fmt(const struct v4l2_format *f)
78{
79 tprints("fmt.");
80 switch (f->type) {
81 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
82 case V4L2_BUF_TYPE_VIDEO_OUTPUT: {
83 const struct v4l2_pix_format *pix = &f->fmt.pix;
84
85 tprintf("pix={width=%u, height=%u, pixelformat=",
86 pix->width, pix->height);
87 print_pixelformat(pix->pixelformat);
88 tprints(", field=");
89 printxval(v4l2_fields, pix->field, "V4L2_FIELD_???");
90 tprintf(", bytesperline=%u, sizeimage=%u, colorspace=",
91 pix->bytesperline, pix->sizeimage);
92 printxval(v4l2_colorspaces, pix->colorspace,
93 "V4L2_COLORSPACE_???");
94 tprints("}");
95 break;
96 }
97#if HAVE_DECL_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
98 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
99 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: {
100 const struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
101 unsigned int i, max;
102
103 tprintf("pix_mp={width=%u, height=%u, pixelformat=",
104 pix_mp->width, pix_mp->height);
105 print_pixelformat(pix_mp->pixelformat);
106 tprints(", field=");
107 printxval(v4l2_fields, pix_mp->field, "V4L2_FIELD_???");
108 tprints(", colorspace=");
109 printxval(v4l2_colorspaces, pix_mp->colorspace,
110 "V4L2_COLORSPACE_???");
111 tprints("plane_fmt=[");
112 max = pix_mp->num_planes;
113 if (max > VIDEO_MAX_PLANES)
114 max = VIDEO_MAX_PLANES;
115 for (i = 0; i < max; i++) {
116 if (i > 0)
117 tprints(", ");
118 tprintf("{sizeimage=%u, bytesperline=%u}",
119 pix_mp->plane_fmt[i].sizeimage,
120 pix_mp->plane_fmt[i].bytesperline);
121 }
122 tprintf("], num_planes=%u}", (unsigned) pix_mp->num_planes);
123 break;
124 }
125#endif
126
127 /* TODO: Complete this switch statement */
128 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
Dmitry V. Levin197db572015-01-09 04:53:19 +0000129#if HAVE_DECL_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100130 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
Dmitry V. Levin197db572015-01-09 04:53:19 +0000131#endif
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100132 tprints("win={???}");
133 break;
134
135 case V4L2_BUF_TYPE_VBI_CAPTURE:
136 case V4L2_BUF_TYPE_VBI_OUTPUT:
137 tprints("vbi={???}");
138 break;
139
140 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
141 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
142 tprints("sliced={???}");
143 break;
144
145 default:
146 tprints("???");
147 break;
148 }
149}
150
151int
Dmitry V. Levinc7afb482015-01-19 18:44:21 +0000152v4l2_ioctl(struct tcb *tcp, const unsigned int code, long arg)
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100153{
154 if (!verbose(tcp))
155 return 0;
156
157 switch (code) {
158 case VIDIOC_QUERYCAP: /* decode on exit */ {
159 struct v4l2_capability caps;
160
161 if (entering(tcp) || syserror(tcp) || umove(tcp, arg, &caps) < 0)
162 return 0;
Dmitry V. Levin1de59cf2015-01-26 02:45:09 +0000163 tprints(", {driver=");
164 print_quoted_string((const char *) caps.driver,
165 sizeof(caps.driver), QUOTE_0_TERMINATED);
166 tprints(", card=");
167 print_quoted_string((const char *) caps.card,
168 sizeof(caps.card), QUOTE_0_TERMINATED);
169 tprints(", bus_info=");
170 print_quoted_string((const char *) caps.bus_info,
171 sizeof(caps.bus_info), QUOTE_0_TERMINATED);
172 tprintf(", version=%u.%u.%u, capabilities=",
173 (caps.version >> 16) & 0xFF,
174 (caps.version >> 8) & 0xFF,
175 caps.version & 0xFF);
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100176 printflags(v4l2_device_capabilities_flags, caps.capabilities,
177 "V4L2_CAP_???");
178#ifdef V4L2_CAP_DEVICE_CAPS
179 tprints(", device_caps=");
180 printflags(v4l2_device_capabilities_flags, caps.device_caps,
181 "V4L2_CAP_???");
182#endif
183 tprints("}");
184 return 1;
185 }
186
Dmitry V. Levin197db572015-01-09 04:53:19 +0000187#ifdef VIDIOC_ENUM_FRAMESIZES
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100188 case VIDIOC_ENUM_FRAMESIZES: /* decode on exit */ {
189 struct v4l2_frmsizeenum s;
190
191 if (entering(tcp) || umove(tcp, arg, &s) < 0)
192 return 0;
193 tprintf(", {index=%u, pixel_format=", s.index);
194 print_pixelformat(s.pixel_format);
195
196 if (!syserror(tcp)) {
197 tprints(", type=");
198 printxval(v4l2_framesize_types, s.type, "V4L2_FRMSIZE_TYPE_???");
199 switch (s.type) {
200 case V4L2_FRMSIZE_TYPE_DISCRETE:
201 tprintf(", discrete={width=%u, height=%u}",
202 s.discrete.width, s.discrete.height);
203 break;
204 case V4L2_FRMSIZE_TYPE_STEPWISE:
205 tprintf(", stepwise={min_width=%u, max_width=%u, "
206 "step_width=%u, min_height=%u, max_height=%u, "
207 "step_height=%u}",
208 s.stepwise.min_width, s.stepwise.max_width,
209 s.stepwise.step_width, s.stepwise.min_height,
210 s.stepwise.max_height, s.stepwise.step_height);
211 break;
212 }
213 }
214 tprints("}");
215 return 1;
216 }
Dmitry V. Levin197db572015-01-09 04:53:19 +0000217#endif /* VIDIOC_ENUM_FRAMESIZES */
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100218
219 case VIDIOC_G_FMT:
220 case VIDIOC_S_FMT:
221 case VIDIOC_TRY_FMT: {
222 struct v4l2_format f;
223
224 if (umove(tcp, arg, &f) < 0)
225 return 0;
226 if (entering(tcp)) {
227 tprints(", {type=");
228 printxval(v4l2_buf_types, f.type, "V4L2_BUF_TYPE_???");
229 }
230 if ((entering(tcp) && code != VIDIOC_G_FMT)
231 || (exiting(tcp) && !syserror(tcp))) {
232 tprints(exiting(tcp) && code != VIDIOC_G_FMT ? " => " : ", ");
233 print_v4l2_format_fmt(&f);
234 }
235 if (exiting(tcp))
236 tprints("}");
237 return 1;
238 }
239
240 case VIDIOC_ENUM_FMT: {
241 struct v4l2_fmtdesc f;
242
243 if (entering(tcp) || umove(tcp, arg, &f) < 0)
244 return 0;
245
246 tprintf(", {index=%u", f.index);
247 if (!syserror(tcp)) {
248 tprints(", type=");
249 printxval(v4l2_buf_types, f.type, "V4L2_BUF_TYPE_???");
250 tprints(", flags=");
251 printflags(v4l2_format_description_flags, f.flags,
252 "V4L2_FMT_FLAG_???");
Dmitry V. Levin1de59cf2015-01-26 02:45:09 +0000253 tprints(", description=");
254 print_quoted_string((const char *) f.description,
255 sizeof(f.description),
256 QUOTE_0_TERMINATED);
257 tprints(", pixelformat=");
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100258 print_pixelformat(f.pixelformat);
259 }
260 tprints("}");
261 return 1;
262 }
263
264 case VIDIOC_G_PARM:
265 case VIDIOC_S_PARM: {
266 struct v4l2_streamparm s;
267
268 if (entering(tcp) && code == VIDIOC_G_PARM)
269 return 1;
270 if (exiting(tcp) && syserror(tcp))
271 return code == VIDIOC_S_PARM;
272 if (umove(tcp, arg, &s) < 0)
273 return 0;
274 if (entering(tcp)) {
275 tprints(", {type=");
276 printxval(v4l2_buf_types, s.type, "V4L2_BUF_TYPE_???");
277 }
278
279 tprints(exiting(tcp) && code == VIDIOC_S_PARM ? " => {" : ", {");
280 if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
281 struct v4l2_captureparm *cap = &s.parm.capture;
282
283 tprints("capability=");
284 printflags(v4l2_streaming_capabilities,
285 cap->capability, "V4L2_CAP_???");
286
287 tprints(", capturemode=");
288 printflags(v4l2_capture_modes,
289 cap->capturemode, "V4L2_MODE_???");
290
291 tprintf(", timeperframe=" FMT_FRACT,
292 ARGS_FRACT(cap->timeperframe));
293
294 tprintf(", extendedmode=%u, readbuffers=%u",
295 cap->extendedmode,
296 cap->readbuffers);
297 } else
298 tprints("...");
299 tprints("}");
300 if (exiting(tcp))
301 tprints("}");
302 return 1;
303 }
304
305 case VIDIOC_QUERYCTRL: {
306 struct v4l2_queryctrl c;
307
308 if (umove(tcp, arg, &c) < 0)
309 return 0;
310 /* 'id' field must be printed :
311 * on enter
312 * on exit if !syserror(tcp) && V4L2_CTRL_FLAG_NEXT_CTRL was set
313 */
314 if (entering(tcp)
315 || (exiting(tcp) && tcp->auxstr && !syserror(tcp))) {
316 tprints(exiting(tcp) ? " => " : ", {id=");
317 tcp->auxstr = (c.id & V4L2_CTRL_FLAG_NEXT_CTRL) ? "" : NULL;
318 if (tcp->auxstr) {
319 tprints("V4L2_CTRL_FLAG_NEXT_CTRL|");
320 c.id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
321 }
322 printxval(v4l2_control_ids, c.id, "V4L2_CID_???");
323 }
324 if (exiting(tcp)) {
325 if (!syserror(tcp)) {
326 tprints(", type=");
327 printxval(v4l2_control_types, c.type,
328 "V4L2_CTRL_TYPE_???");
Dmitry V. Levin1de59cf2015-01-26 02:45:09 +0000329 tprints(", name=");
330 print_quoted_string((const char *) c.name,
331 sizeof(c.name),
332 QUOTE_0_TERMINATED);
333 tprintf(", minimum=%i, maximum=%i, step=%i, "
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100334 "default_value=%i, flags=",
Dmitry V. Levin1de59cf2015-01-26 02:45:09 +0000335 c.minimum, c.maximum,
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100336 c.step, c.default_value);
337 printflags(v4l2_control_flags, c.flags,
338 "V4L2_CTRL_FLAG_???");
339 }
340 tprints("}");
341 }
342 return 1;
343 }
344
345 case VIDIOC_G_CTRL:
346 case VIDIOC_S_CTRL: {
347 struct v4l2_control c;
348
349 if (entering(tcp) || umove(tcp, arg, &c) < 0)
350 return 0;
351 tprints(", {id=");
352 printxval(v4l2_control_ids, c.id, "V4L2_CID_???");
353 if (!syserror(tcp) || code != VIDIOC_G_CTRL)
354 tprintf(", value=%i", c.value);
355 tprints("}");
356 return 1;
357 }
358
359 case VIDIOC_S_EXT_CTRLS:
360 case VIDIOC_TRY_EXT_CTRLS:
361 case VIDIOC_G_EXT_CTRLS: {
362 struct v4l2_ext_controls c;
363 unsigned int n;
364 bool must_print_values;
365
366 if (entering(tcp) && code == VIDIOC_G_EXT_CTRLS)
367 return 0;
368 if (exiting(tcp) && syserror(tcp) && code != VIDIOC_G_EXT_CTRLS)
369 return 0;
370 must_print_values = ((entering(tcp) && code != VIDIOC_G_EXT_CTRLS)
371 || (exiting(tcp) && !syserror(tcp)));
372 if (umove(tcp, arg, &c) < 0)
373 return 0;
374 tprints(code != VIDIOC_G_EXT_CTRLS && exiting(tcp) ? " => " : ", ");
375 tprints("{ctrl_class=");
376 printxval(v4l2_control_classes, c.ctrl_class,
377 "V4L2_CTRL_CLASS_???");
378 tprintf(", count=%u", c.count);
379 if (exiting(tcp) && syserror(tcp))
380 tprintf(", error_idx=%u", c.error_idx);
381 tprints(", controls=[");
382 for (n = 0; n < c.count; ++n) {
383 struct v4l2_ext_control ctrl;
384
385 if (n > 0)
386 tprints(", ");
387 if (umove(tcp, (long) (c.controls + n), &ctrl) < 0)
388 break;
389 if (abbrev(tcp) && n == 2) {
390 tprints("...");
391 break;
392 }
393 tprints("{id=");
394 printxval(v4l2_control_ids, ctrl.id, "V4L2_CID_???");
395#if HAVE_DECL_V4L2_CTRL_TYPE_STRING
396 tprintf(", size=%u", ctrl.size);
397 if (ctrl.size > 0) {
398 if (must_print_values) {
399 tprints(", string=");
400 printstr(tcp, (long) ctrl.string, ctrl.size);
401 }
402 } else
403#endif
404 {
405 if (must_print_values) {
406 tprintf(", value=%i, value64=%lli", ctrl.value,
407 ctrl.value64);
408 }
409 }
410 tprints("}");
411 }
412 tprints("]}");
413 return 1;
414 }
415
416 case VIDIOC_ENUMSTD: {
417 struct v4l2_standard s;
418
419 if (umove(tcp, arg, &s) < 0)
420 return 0;
421 if (entering(tcp))
422 tprintf(", {index=%i", s.index);
423 else {
424 if (!syserror(tcp)) {
Dmitry V. Levin1de59cf2015-01-26 02:45:09 +0000425 tprints(", name=");
426 print_quoted_string((const char *) s.name,
427 sizeof(s.name),
428 QUOTE_0_TERMINATED);
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100429 tprintf(", frameperiod=" FMT_FRACT, ARGS_FRACT(s.frameperiod));
430 tprintf(", framelines=%i", s.framelines);
431 }
432 tprints("}");
433 }
434 return 1;
435 }
436
437 case VIDIOC_G_STD:
438 case VIDIOC_S_STD: {
439 v4l2_std_id s;
440
441 if (code == VIDIOC_G_STD && exiting(tcp) && syserror(tcp))
442 return 0;
443 if (umove(tcp, arg, &s) < 0)
444 return 0;
445 if ((code == VIDIOC_S_STD) == entering(tcp))
446 tprintf(", std=%#llx", s);
447 return 1;
448 }
449
450 case VIDIOC_ENUMINPUT: {
451 struct v4l2_input i;
452
453 if (entering(tcp) || umove(tcp, arg, &i) < 0)
454 return 0;
455 tprintf(", {index=%i", i.index);
456 if (!syserror(tcp)) {
Dmitry V. Levin1de59cf2015-01-26 02:45:09 +0000457 tprints(", name=");
458 print_quoted_string((const char *) i.name,
459 sizeof(i.name), QUOTE_0_TERMINATED);
460 tprints(", type=");
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100461 printxval(v4l2_input_types, i.type,
462 "V4L2_INPUT_TYPE_???");
463 }
464 tprints("}");
465 return 1;
466 }
467
468 case VIDIOC_G_INPUT:
469 case VIDIOC_S_INPUT: {
470 int index;
471
472 if (entering(tcp) || syserror(tcp) || umove(tcp, arg, &index) < 0)
473 return 0;
474
475 tprintf(", index=%i", index);
476 return 1;
477 }
478
Dmitry V. Levin197db572015-01-09 04:53:19 +0000479#ifdef VIDIOC_ENUM_FRAMEINTERVALS
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100480 case VIDIOC_ENUM_FRAMEINTERVALS: {
481 struct v4l2_frmivalenum f;
482
483 if (entering(tcp) || umove(tcp, arg, &f) < 0)
484 return 0;
485 tprintf(", {index=%i, pixel_format=", f.index);
486 print_pixelformat(f.pixel_format);
487 tprintf(", width=%u, height=%u", f.width, f.height);
488 if (!syserror(tcp)) {
489 tprints(", type=");
490 printxval(v4l2_frameinterval_types, f.type,
491 "V4L2_FRMIVAL_TYPE_???");
492 switch (f.type) {
493 case V4L2_FRMIVAL_TYPE_DISCRETE:
494 tprintf(", discrete=" FMT_FRACT,
495 ARGS_FRACT(f.discrete));
496 break;
497 case V4L2_FRMIVAL_TYPE_STEPWISE:
498 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
499 tprintf(", stepwise={min=" FMT_FRACT ", max="
500 FMT_FRACT ", step=" FMT_FRACT "}",
501 ARGS_FRACT(f.stepwise.min),
502 ARGS_FRACT(f.stepwise.max),
503 ARGS_FRACT(f.stepwise.step));
504 break;
505 }
506 }
507 tprints("}");
508 return 1;
509 }
Dmitry V. Levin197db572015-01-09 04:53:19 +0000510#endif /* VIDIOC_ENUM_FRAMEINTERVALS */
Philippe De Muyter0cc96142014-11-03 21:27:40 +0100511
512 case VIDIOC_CROPCAP: {
513 struct v4l2_cropcap c;
514
515 if (entering(tcp) || umove(tcp, arg, &c) < 0)
516 return 0;
517 tprints(", type=");
518 printxval(v4l2_buf_types, c.type, "V4L2_BUF_TYPE_???");
519 if (syserror(tcp))
520 return 1;
521 tprintf(", bounds=" FMT_RECT ", defrect=" FMT_RECT ", "
522 "pixelaspect=" FMT_FRACT, ARGS_RECT(c.bounds),
523 ARGS_RECT(c.defrect), ARGS_FRACT(c.pixelaspect));
524 return 1;
525 }
526
527 case VIDIOC_G_FBUF:
528 case VIDIOC_S_FBUF: {
529 struct v4l2_framebuffer b;
530
531 if (syserror(tcp) && code == VIDIOC_G_FBUF)
532 return 0;
533 if (entering(tcp) || umove(tcp, arg, &b) < 0)
534 return 0;
535 tprintf(", {capability=%x, flags=%x, base=%p}",
536 b.capability, b.flags, b.base);
537 return 1;
538 }
539
540 case VIDIOC_REQBUFS: {
541 struct v4l2_requestbuffers reqbufs;
542
543 if (umove(tcp, arg, &reqbufs) < 0)
544 return 0;
545 if (entering(tcp)) {
546 tprintf(", {count=%u, type=", reqbufs.count);
547 printxval(v4l2_buf_types, reqbufs.type, "V4L2_BUF_TYPE_???");
548 tprints(", memory=");
549 printxval(v4l2_memories, reqbufs.memory, "V4L2_MEMORY_???");
550 tprints("}");
551 return 1;
552 } else if (syserror(tcp))
553 return 1;
554 else {
555 static char outstr[sizeof("{count=}") + sizeof(int) * 3];
556
557 sprintf(outstr, "{count=%u}", reqbufs.count);
558 tcp->auxstr = outstr;
559 return 1 + RVAL_STR;
560 }
561 }
562
563 case VIDIOC_QUERYBUF:
564 case VIDIOC_QBUF:
565 case VIDIOC_DQBUF: {
566 struct v4l2_buffer b;
567
568 if (umove(tcp, arg, &b) < 0)
569 return 0;
570 if (entering(tcp)) {
571 tprints(", {type=");
572 printxval(v4l2_buf_types, b.type, "V4L2_BUF_TYPE_???");
573 if (code != VIDIOC_DQBUF)
574 tprintf(", index=%u", b.index);
575 } else {
576 if (!syserror(tcp)) {
577 if (code == VIDIOC_DQBUF)
578 tprintf(", index=%u", b.index);
579 tprints(", memory=");
580 printxval(v4l2_memories, b.memory, "V4L2_MEMORY_???");
581
582 if (b.memory == V4L2_MEMORY_MMAP) {
583 tprintf(", m.offset=%#x", b.m.offset);
584 } else if (b.memory == V4L2_MEMORY_USERPTR) {
585 tprintf(", m.userptr=%#lx", b.m.userptr);
586 }
587
588 tprintf(", length=%u, bytesused=%u, flags=",
589 b.length, b.bytesused);
590 printflags(v4l2_buf_flags, b.flags, "V4L2_BUF_FLAG_???");
591 if (code == VIDIOC_DQBUF)
592 tprintf(", timestamp = {%lu.%06lu}",
593 b.timestamp.tv_sec,
594 b.timestamp.tv_usec);
595 tprints(", ...");
596 }
597 tprints("}");
598 }
599 return 1;
600 }
601
602 case VIDIOC_STREAMON:
603 case VIDIOC_STREAMOFF: {
604 int type;
605
606 if (umove(tcp, arg, &type) < 0)
607 return 0;
608 if (entering(tcp)) {
609 tprints(", ");
610 printxval(v4l2_buf_types, type, "V4L2_BUF_TYPE_???");
611 }
612 return 1;
613 }
614
615 default: /* decode on exit */
616 return 0;
617 }
618}