---
 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 <w...@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


------------------------------------------------------------------------------
Subversion Kills Productivity. Get off Subversion & Make the Move to Perforce.
With Perforce, you get hassle-free workflows. Merge that actually works. 
Faster operations. Version large binaries.  Built-in WAN optimization and the
freedom to use Git, Perforce or both. Make the move to Perforce.
http://pubads.g.doubleclick.net/gampad/clk?id=122218951&iu=/4140/ostg.clktrk
_______________________________________________
Strace-devel mailing list
Strace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to