[PATCH] Add (incomplete) decoder for Video4Linux ioctls
William Manley
will at williammanley.net
Tue Mar 4 17:41:27 UTC 2014
---
Makefile.am | 1 +
defs.h | 1 +
ioctl.c | 2 +
v4l2.c | 529 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 533 insertions(+)
create mode 100644 v4l2.c
diff --git a/Makefile.am b/Makefile.am
index 03d310b..c510463 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ strace_SOURCES = \
term.c \
time.c \
util.c \
+ v4l2.c \
vsprintf.c
noinst_HEADERS = defs.h
diff --git a/defs.h b/defs.h
index f457d30..1f80ea1 100644
--- a/defs.h
+++ b/defs.h
@@ -707,6 +707,7 @@ extern int mtd_ioctl(struct tcb *, long, long);
extern int ubi_ioctl(struct tcb *, long, long);
extern int loop_ioctl(struct tcb *, long, long);
extern int ptp_ioctl(struct tcb *, long, long);
+extern int v4l2_ioctl(struct tcb *, unsigned long, long);
extern int tv_nz(struct timeval *);
extern int tv_cmp(struct timeval *, struct timeval *);
diff --git a/ioctl.c b/ioctl.c
index 3f6c410..451fe31 100644
--- a/ioctl.c
+++ b/ioctl.c
@@ -97,6 +97,8 @@ ioctl_decode(struct tcb *tcp, long code, long arg)
case 'o':
case 'O':
return ubi_ioctl(tcp, code, arg);
+ case 'V':
+ return v4l2_ioctl(tcp, code, arg);
case '=':
return ptp_ioctl(tcp, code, arg);
default:
diff --git a/v4l2.c b/v4l2.c
new file mode 100644
index 0000000..1a8c436
--- /dev/null
+++ b/v4l2.c
@@ -0,0 +1,529 @@
+/*
+ * Copyright (c) 2014 William Manley <will at williammanley.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+#include <sys/ioctl.h>
+#include <linux/videodev2.h>
+
+static const struct xlat device_capabilities_flags[] = {
+ XLAT(V4L2_CAP_VIDEO_CAPTURE),
+ XLAT(V4L2_CAP_VIDEO_OUTPUT),
+ XLAT(V4L2_CAP_VIDEO_OVERLAY),
+ XLAT(V4L2_CAP_VBI_CAPTURE),
+ XLAT(V4L2_CAP_VBI_OUTPUT),
+ XLAT(V4L2_CAP_SLICED_VBI_CAPTURE),
+ XLAT(V4L2_CAP_SLICED_VBI_OUTPUT),
+ XLAT(V4L2_CAP_RDS_CAPTURE),
+ XLAT(V4L2_CAP_VIDEO_OUTPUT_OVERLAY),
+ XLAT(V4L2_CAP_HW_FREQ_SEEK),
+ XLAT(V4L2_CAP_RDS_OUTPUT),
+ XLAT(V4L2_CAP_VIDEO_CAPTURE_MPLANE),
+ XLAT(V4L2_CAP_VIDEO_OUTPUT_MPLANE),
+ XLAT(V4L2_CAP_VIDEO_M2M),
+ XLAT(V4L2_CAP_VIDEO_M2M_MPLANE),
+ XLAT(V4L2_CAP_TUNER),
+ XLAT(V4L2_CAP_AUDIO),
+ XLAT(V4L2_CAP_RADIO),
+ XLAT(V4L2_CAP_MODULATOR),
+ XLAT(V4L2_CAP_READWRITE),
+ XLAT(V4L2_CAP_ASYNCIO),
+ XLAT(V4L2_CAP_STREAMING),
+ XLAT(V4L2_CAP_DEVICE_CAPS),
+ XLAT_END
+};
+
+static const struct xlat v4l2_formats[] = {
+ XLAT(V4L2_BUF_TYPE_VIDEO_CAPTURE),
+ XLAT(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ),
+ XLAT(V4L2_BUF_TYPE_VIDEO_OUTPUT),
+ XLAT(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ),
+ XLAT(V4L2_BUF_TYPE_VIDEO_OVERLAY),
+ XLAT(V4L2_BUF_TYPE_VBI_CAPTURE),
+ XLAT(V4L2_BUF_TYPE_VBI_OUTPUT),
+ XLAT(V4L2_BUF_TYPE_SLICED_VBI_CAPTURE),
+ XLAT(V4L2_BUF_TYPE_SLICED_VBI_OUTPUT),
+ XLAT(V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY),
+ XLAT_END
+};
+
+static const struct xlat v4l2_framesize_types[] = {
+ XLAT(V4L2_FRMSIZE_TYPE_DISCRETE),
+ XLAT(V4L2_FRMSIZE_TYPE_CONTINUOUS),
+ XLAT(V4L2_FRMSIZE_TYPE_STEPWISE),
+ XLAT_END
+};
+
+static const struct xlat v4l2_frameinterval_types[] = {
+ XLAT(V4L2_FRMIVAL_TYPE_DISCRETE),
+ XLAT(V4L2_FRMIVAL_TYPE_CONTINUOUS),
+ XLAT(V4L2_FRMIVAL_TYPE_STEPWISE),
+ XLAT_END
+};
+
+static const struct xlat v4l2_fields[] = {
+ XLAT(V4L2_FIELD_ANY),
+ XLAT(V4L2_FIELD_NONE),
+ XLAT(V4L2_FIELD_TOP),
+ XLAT(V4L2_FIELD_BOTTOM),
+ XLAT(V4L2_FIELD_INTERLACED),
+ XLAT(V4L2_FIELD_SEQ_TB),
+ XLAT(V4L2_FIELD_SEQ_BT),
+ XLAT(V4L2_FIELD_ALTERNATE),
+ XLAT(V4L2_FIELD_INTERLACED_TB),
+ XLAT(V4L2_FIELD_INTERLACED_BT),
+ XLAT_END
+};
+
+static const struct xlat v4l2_colorspaces[] = {
+ XLAT(V4L2_COLORSPACE_SMPTE170M),
+ XLAT(V4L2_COLORSPACE_SMPTE240M),
+ XLAT(V4L2_COLORSPACE_REC709),
+ XLAT(V4L2_COLORSPACE_BT878),
+ XLAT(V4L2_COLORSPACE_470_SYSTEM_M),
+ XLAT(V4L2_COLORSPACE_470_SYSTEM_BG),
+ XLAT(V4L2_COLORSPACE_JPEG),
+ XLAT(V4L2_COLORSPACE_SRGB),
+ XLAT_END
+};
+
+static const struct xlat v4l2_format_description_flags[] = {
+ XLAT(V4L2_FMT_FLAG_COMPRESSED),
+ XLAT(V4L2_FMT_FLAG_EMULATED),
+ XLAT_END
+};
+
+static const struct xlat v4l2_control_ids[] = {
+ XLAT(V4L2_CID_BRIGHTNESS),
+ XLAT(V4L2_CID_CONTRAST),
+ XLAT(V4L2_CID_SATURATION),
+ XLAT(V4L2_CID_HUE),
+ XLAT(V4L2_CID_AUDIO_VOLUME),
+ XLAT(V4L2_CID_AUDIO_BALANCE),
+ XLAT(V4L2_CID_AUDIO_BASS),
+ XLAT(V4L2_CID_AUDIO_TREBLE),
+ XLAT(V4L2_CID_AUDIO_MUTE),
+ XLAT(V4L2_CID_AUDIO_LOUDNESS),
+ XLAT(V4L2_CID_BLACK_LEVEL),
+ XLAT(V4L2_CID_AUTO_WHITE_BALANCE),
+ XLAT(V4L2_CID_DO_WHITE_BALANCE),
+ XLAT(V4L2_CID_RED_BALANCE),
+ XLAT(V4L2_CID_BLUE_BALANCE),
+ XLAT(V4L2_CID_GAMMA),
+ XLAT(V4L2_CID_WHITENESS),
+ XLAT(V4L2_CID_EXPOSURE),
+ XLAT(V4L2_CID_AUTOGAIN),
+ XLAT(V4L2_CID_GAIN),
+ XLAT(V4L2_CID_HFLIP),
+ XLAT(V4L2_CID_VFLIP),
+ XLAT(V4L2_CID_POWER_LINE_FREQUENCY),
+ XLAT(V4L2_CID_HUE_AUTO),
+ XLAT(V4L2_CID_WHITE_BALANCE_TEMPERATURE),
+ XLAT(V4L2_CID_SHARPNESS),
+ XLAT(V4L2_CID_BACKLIGHT_COMPENSATION),
+ XLAT(V4L2_CID_CHROMA_AGC),
+ XLAT(V4L2_CID_CHROMA_GAIN),
+ XLAT(V4L2_CID_COLOR_KILLER),
+ XLAT(V4L2_CID_COLORFX),
+ XLAT(V4L2_CID_COLORFX_CBCR),
+ XLAT(V4L2_CID_AUTOBRIGHTNESS),
+ XLAT(V4L2_CID_ROTATE),
+ XLAT(V4L2_CID_BG_COLOR),
+ XLAT(V4L2_CID_ILLUMINATORS_1),
+ XLAT(V4L2_CID_ILLUMINATORS_2),
+ XLAT(V4L2_CID_MIN_BUFFERS_FOR_CAPTURE),
+ XLAT(V4L2_CID_MIN_BUFFERS_FOR_OUTPUT),
+ XLAT(V4L2_CID_ALPHA_COMPONENT),
+ XLAT_END
+};
+
+static const struct xlat v4l2_control_types[] = {
+ XLAT(V4L2_CTRL_TYPE_INTEGER),
+ XLAT(V4L2_CTRL_TYPE_BOOLEAN),
+ XLAT(V4L2_CTRL_TYPE_MENU),
+ XLAT(V4L2_CTRL_TYPE_INTEGER_MENU),
+ XLAT(V4L2_CTRL_TYPE_BITMASK),
+ XLAT(V4L2_CTRL_TYPE_BUTTON),
+ XLAT(V4L2_CTRL_TYPE_INTEGER64),
+ XLAT(V4L2_CTRL_TYPE_STRING),
+ XLAT(V4L2_CTRL_TYPE_CTRL_CLASS),
+ XLAT_END
+};
+
+static const struct xlat v4l2_control_flags[] = {
+ XLAT(V4L2_CTRL_FLAG_DISABLED),
+ XLAT(V4L2_CTRL_FLAG_GRABBED),
+ XLAT(V4L2_CTRL_FLAG_READ_ONLY),
+ XLAT(V4L2_CTRL_FLAG_UPDATE),
+ XLAT(V4L2_CTRL_FLAG_INACTIVE),
+ XLAT(V4L2_CTRL_FLAG_SLIDER),
+ XLAT(V4L2_CTRL_FLAG_WRITE_ONLY),
+ XLAT(V4L2_CTRL_FLAG_VOLATILE),
+ XLAT_END
+};
+
+static const struct xlat v4l2_control_classes[] = {
+ XLAT(V4L2_CTRL_CLASS_USER),
+ XLAT(V4L2_CTRL_CLASS_MPEG),
+ XLAT(V4L2_CTRL_CLASS_CAMERA),
+ XLAT(V4L2_CTRL_CLASS_FM_TX),
+ XLAT(V4L2_CTRL_CLASS_FLASH),
+ XLAT(V4L2_CTRL_CLASS_JPEG),
+ XLAT(V4L2_CTRL_CLASS_IMAGE_SOURCE),
+ XLAT(V4L2_CTRL_CLASS_IMAGE_PROC),
+ XLAT(V4L2_CTRL_CLASS_FM_RX),
+ XLAT_END
+};
+
+#define PRINTF_FOURCC "%c%c%c%c"
+#define FOURCC(x) (char) (x), (char) (x>>8), (char) (x>>16), (char) (x>>24)
+
+#define PRINTF_FRACT "%u/%u"
+#define FRACT(x) ((x).numerator), ((x).denominator)
+
+#define PRINTF_RECT "{left=%i, top=%i, width=%i, height=%i}"
+#define RECT(x) (x).left, (x).top, (x).width, (x).height
+
+static void print_v4l2_format(const struct v4l2_format* fmt)
+{
+ tprintf("type=");
+ printxval(v4l2_formats, fmt->type, "V4L2_BUF_TYPE_???");
+ tprintf(", fmt={");
+ switch (fmt->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ tprintf("pix={width=%u, height=%u, pixelformat=" PRINTF_FOURCC ", "
+ "field=", fmt->fmt.pix.width, fmt->fmt.pix.height,
+ FOURCC(fmt->fmt.pix.pixelformat));
+ printxval(v4l2_fields, fmt->fmt.pix.field, "V4L2_FIELD_???");
+ tprintf(", bytesperline=%u, sizeimage=%u, colorspace=",
+ fmt->fmt.pix.bytesperline, fmt->fmt.pix.sizeimage);
+ printxval(v4l2_colorspaces, fmt->fmt.pix.colorspace,
+ "V4L2_COLORSPACE_???");
+ tprintf("}");
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
+ {
+ int i;
+ tprintf("pix={width=%u, height=%u, pixelformat=" PRINTF_FOURCC ", "
+ "field=", fmt->fmt.pix_mp.width, fmt->fmt.pix_mp.height,
+ FOURCC(fmt->fmt.pix_mp.pixelformat));
+ printxval(v4l2_fields, fmt->fmt.pix_mp.field, "V4L2_FIELD_???");
+
+ tprintf(", colorspace=");
+ printxval(v4l2_colorspaces, fmt->fmt.pix_mp.colorspace,
+ "V4L2_COLORSPACE_???");
+
+ tprintf("plane_fmt=[");
+ for (i=0; i<fmt->fmt.pix_mp.num_planes; i++) {
+ if (i>0)
+ tprintf(", ");
+ tprintf("{sizeimage=%u, bytesperline=%u}",
+ fmt->fmt.pix_mp.plane_fmt[i].sizeimage,
+ fmt->fmt.pix_mp.plane_fmt[i].bytesperline);
+ }
+ tprintf("], num_planes=%u", (unsigned) fmt->fmt.pix_mp.num_planes);
+ break;
+ }
+
+ /* TODO: Complete this switch statement */
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ tprintf("win={???}");
+ break;
+
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ tprintf("vbi={???}");
+ break;
+
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ tprintf("sliced={???}");
+ break;
+ default:
+ tprintf("???");
+ break;
+ }
+ tprintf("}");
+}
+
+int v4l2_ioctl(struct tcb *tcp, unsigned long code, long arg)
+{
+ if (!verbose(tcp))
+ return 0;
+
+ switch (code) {
+ case VIDIOC_QUERYCAP: /* decode on exit */
+ {
+ struct v4l2_capability caps;
+ if (entering(tcp) || syserror(tcp) || umove(tcp, arg, &caps) < 0)
+ return 0;
+
+ tprintf(", {driver=\"%s\", card=\"%s\", bus_info=\"%s\", "
+ "version=%u.%u.%u, capabilities=", caps.driver, caps.card,
+ caps.bus_info, (caps.version >> 16) & 0xFF,
+ (caps.version >> 8) & 0xFF, caps.version & 0xFF);
+ printflags(device_capabilities_flags, caps.capabilities,
+ "V4L2_CAP_???");
+ tprintf(", device_caps=");
+ printflags(device_capabilities_flags, caps.device_caps,
+ "V4L2_CAP_???");
+ tprintf(")");
+ return 1;
+ }
+
+ case VIDIOC_ENUM_FRAMESIZES: /* decode on exit */
+ {
+ struct v4l2_frmsizeenum s;
+ if (entering(tcp) || umove(tcp, arg, &s) < 0)
+ return 0;
+
+ tprintf(", index=%u, pixel_format=" PRINTF_FOURCC, s.index,
+ FOURCC(s.pixel_format));
+
+ if (syserror(tcp))
+ return 1;
+
+ tprintf(", type=");
+ printxval(v4l2_framesize_types, s.type, "V4L2_FRMSIZE_TYPE_???");
+ switch (s.type) {
+ case V4L2_FRMSIZE_TYPE_DISCRETE:
+ tprintf(", discrete={width=%u, height=%u}",
+ s.discrete.width, s.discrete.height);
+ break;
+ case V4L2_FRMSIZE_TYPE_STEPWISE:
+ tprintf(", stepwise={min_width=%u, max_width=%u, "
+ "step_width=%u, min_height=%u, max_height=%u, "
+ "step_height=%u}",
+ s.stepwise.min_width, s.stepwise.max_width,
+ s.stepwise.step_width, s.stepwise.min_height,
+ s.stepwise.max_height, s.stepwise.step_height);
+ break;
+ }
+ tprintf(")");
+ return 1;
+ }
+
+ case VIDIOC_G_FMT:
+ {
+ struct v4l2_format f;
+ if (entering(tcp) || syserror(tcp) || umove(tcp, arg, &f) < 0)
+ return 0;
+
+ tprintf(", ");
+ print_v4l2_format(&f);
+ return 1;
+ }
+
+ case VIDIOC_TRY_FMT:
+ case VIDIOC_S_FMT:
+ {
+ /* TODO: work out how strace deals with inout arguments and
+ implement */
+ return 0;
+ }
+
+ case VIDIOC_ENUM_FMT:
+ {
+ struct v4l2_fmtdesc f;
+
+ if (entering(tcp) || syserror(tcp) || umove(tcp, arg, &f) < 0)
+ return 0;
+
+ tprintf(", index=%u, type=", f.index);
+ printxval(v4l2_formats, f.type, "V4L2_BUF_TYPE_???");
+ tprintf(", flags=");
+ printflags(v4l2_format_description_flags, f.flags,
+ "V4L2_FMT_FLAG_???");
+ tprintf(", description=\"%s\", pixelformat=" PRINTF_FOURCC,
+ f.description, FOURCC(f.pixelformat));
+ return 1;
+ }
+
+ case VIDIOC_G_PARM:
+ {
+ struct v4l2_streamparm s;
+
+ if (entering(tcp) || umove(tcp, arg, &s) < 0)
+ return 0;
+
+ tprintf(", type=");
+ printxval(v4l2_formats, s.type, "V4L2_BUF_TYPE_???");
+
+ if (syserror(tcp))
+ return 1;
+
+ /* TODO: Decode struct v4l2_captureparm/v4l2_outputparm */
+ tprintf(", parm={???}");
+ return 1;
+ }
+
+ case VIDIOC_S_PARM:
+ {
+ struct v4l2_streamparm s;
+
+ if (entering(tcp) || syserror(tcp) || umove(tcp, arg, &s) < 0)
+ return 0;
+
+ tprintf(", type=");
+ printxval(v4l2_formats, s.type, "V4L2_BUF_TYPE_???");
+ /* TODO: Decode struct v4l2_captureparm/v4l2_outputparm */
+ tprintf(", parm={???}");
+ return 1;
+ }
+
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl c;
+ if (entering(tcp) || syserror(tcp) || umove(tcp, arg, &c) < 0)
+ return 0;
+
+ tprintf(", ");
+ printxval(v4l2_control_ids, c.id, "V4L2_CID_???");
+ tprintf(", type=");
+ printxval(v4l2_control_types, c.type, "V4L2_CTRL_TYPE_???");
+ tprintf(", name=\"%s\", minimum=%i, maximum=%i, step=%i, "
+ "default_value=%i, flags=", c.name, c.minimum, c.maximum,
+ c.step, c.default_value);
+ printflags(v4l2_control_flags, c.flags, "V4L2_CTRL_FLAG_???");
+ return 1;
+ }
+
+ case VIDIOC_G_CTRL:
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control c;
+ if (entering(tcp) || umove(tcp, arg, &c) < 0)
+ return 0;
+
+ tprintf(", id=");
+ printxval(v4l2_control_ids, c.id, "V4L2_CID_???");
+
+ if (syserror(tcp) && code == VIDIOC_G_CTRL)
+ return 1;
+
+ tprintf(", value=%i", c.value);
+ return 1;
+ }
+
+ case VIDIOC_S_EXT_CTRLS:
+ case VIDIOC_TRY_EXT_CTRLS:
+ case VIDIOC_G_EXT_CTRLS:
+ {
+ struct v4l2_ext_controls c;
+ unsigned n;
+
+ if (entering(tcp) || umove(tcp, arg, &c) < 0)
+ return 0;
+
+ tprintf(", ctrl_class=");
+ printxval(v4l2_control_classes, c.ctrl_class,
+ "V4L2_CTRL_CLASS_???");
+ tprintf(", count=%u, error_idx=%u, controls=[", c.count,
+ c.error_idx);
+
+ for (n=0; n<c.count; ++n) {
+ struct v4l2_ext_control ctrl;
+ if (n > 0)
+ tprintf(", ");
+ umove(tcp, (long) (c.controls + n), &ctrl);
+ tprintf("{id=");
+ printxval(v4l2_control_ids, ctrl.id, "V4L2_CID_???");
+ tprintf(", size=%u", ctrl.size);
+ if (ctrl.size > 0) {
+ tprintf(", string=");
+ printstr(tcp, (long) ctrl.string, ctrl.size);
+ }
+ else {
+ tprintf(", value=%i, value64=%lli", ctrl.value,
+ ctrl.value64);
+ }
+ tprintf("}");
+ }
+ return 1;
+ }
+
+ case VIDIOC_G_INPUT:
+ {
+ int index;
+ if (entering(tcp) || syserror(tcp) || umove(tcp, arg, &index) < 0)
+ return 0;
+
+ tprintf(", index=%i", index);
+ return 1;
+ }
+
+ case VIDIOC_ENUM_FRAMEINTERVALS:
+ {
+ struct v4l2_frmivalenum f;
+ if (entering(tcp) || umove(tcp, arg, &f) < 0)
+ return 0;
+
+ tprintf(", index=%i, pixel_format=" PRINTF_FOURCC ", width=%u, "
+ "height=%u", f.index, FOURCC(f.pixel_format), f.width,
+ f.height);
+ if (syserror(tcp))
+ return 1;
+ tprintf(", type=");
+ printxval(v4l2_frameinterval_types, f.type,
+ "V4L2_FRMIVAL_TYPE_???");
+ switch (f.type)
+ {
+ case V4L2_FRMIVAL_TYPE_DISCRETE:
+ tprintf(", discrete=" PRINTF_FRACT, FRACT(f.discrete));
+ break;
+ case V4L2_FRMIVAL_TYPE_STEPWISE:
+ tprintf(", stepwise={min=" PRINTF_FRACT ", max="
+ PRINTF_FRACT ", step=" PRINTF_FRACT "}",
+ FRACT(f.stepwise.min), FRACT(f.stepwise.max),
+ FRACT(f.stepwise.step));
+ break;
+ }
+ return 1;
+ }
+
+ case VIDIOC_CROPCAP:
+ {
+ struct v4l2_cropcap c;
+ if (entering(tcp) || umove(tcp, arg, &c) < 0)
+ return 0;
+
+ tprintf(", type=");
+ printxval(v4l2_formats, c.type, "V4L2_BUF_TYPE_???");
+ if (syserror(tcp))
+ return 1;
+ tprintf(", bounds=" PRINTF_RECT ", defrect=" PRINTF_RECT ", "
+ "pixelaspect=" PRINTF_FRACT, RECT(c.bounds),
+ RECT(c.defrect), FRACT(c.pixelaspect));
+ return 1;
+ }
+
+ default: /* decode on exit */
+ return 0;
+ }
+}
--
1.9.0
More information about the Strace-devel
mailing list