]> granicus.if.org Git - strace/commitdiff
v4l2: Implement decoding of the remaining V4L2_BUF_TYPE_* types
authorEdgar Kaziahmedov <edos@linux.com>
Thu, 13 Apr 2017 23:39:03 +0000 (02:39 +0300)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 13 Apr 2017 23:47:43 +0000 (23:47 +0000)
* v4l2.c: Include "xlat/v4l2_vbi_flags.h" and "xlat/v4l2_sliced_flags.h".
(struct_v4l2_clip): New typedef.  Mpersify it.
(print_v4l2_clip): New function.
(print_v4l2_format_fmt): Use it.  Add struct tcb argument.  Implement
decoding of the remaining V4L2_BUF_TYPE_* types.
* xlat/v4l2_vbi_flags.in: Add V4L2_VBI_UNSYNC and V4L2_VBI_INTERLACED
introduced by linux kernel commit v2.5.46~39^2~23^2~4.
Add V4L2_VBI_ITU_525_F1_START, V4L2_VBI_ITU_525_F2_START,
V4L2_VBI_ITU_625_F1_START, and V4L2_VBI_ITU_625_F2_START introduced by
linux kernel commit v3.17-rc1~112^2~217.
* xlat/v4l2_sliced_flags.in: Add V4L2_SLICED_TELETEXT_B, V4L2_SLICED_VPS,
V4L2_SLICED_CAPTION_525, V4L2_SLICED_WSS_625, V4L2_SLICED_VBI_525, and
V4L2_SLICED_VBI_625 introduced by linux kernel commit v2.6.14-rc2~64.
* configure.ac (AC_CHECK_DECLS): Add V4L2_BUF_TYPE_SDR_CAPTURE and
V4L2_BUF_TYPE_SDR_OUTPUT.
(AC_CHECK_MEMBERS): Add struct v4l2_window.global_alpha and
struct v4l2_sdr_format.buffersize.
* NEWS: Mention this change.

Signed-off-by: Edgar Kaziahmedov <edos@linux.com>
NEWS
configure.ac
v4l2.c
xlat/v4l2_sliced_flags.in [new file with mode: 0644]
xlat/v4l2_vbi_flags.in [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 8eca949c7261552baa719d3ccc449289bc7dd7b8..f7f64f328f5ddb902cc3a656aca19659a3f8d7ee 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,7 @@ Noteworthy changes in release ?.?? (????-??-??)
     architectures.
   * Implemented decoding of statx syscall.
   * Implemented decoding of NS_* ioctl commands.
+  * Implemented decoding of the remaining V4L2_BUF_TYPE_* types.
   * Updated lists of ioctl commands from Linux 4.11.
 
 * Bug fixes
index dc49fdc57024ff31073bfc02b670166be2c5da12..a52ad8808802e72d4035629a90c0bf66f13a2089 100644 (file)
@@ -609,6 +609,8 @@ AC_CHECK_DECLS(m4_normalize([
        V4L2_BUF_TYPE_SLICED_VBI_CAPTURE,
        V4L2_BUF_TYPE_SLICED_VBI_OUTPUT,
        V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY,
+       V4L2_BUF_TYPE_SDR_CAPTURE,
+       V4L2_BUF_TYPE_SDR_OUTPUT,
        V4L2_TUNER_RADIO,
        V4L2_TUNER_ANALOG_TV,
        V4L2_TUNER_DIGITAL_TV,
@@ -648,6 +650,14 @@ AC_CHECK_DECLS(m4_normalize([
 #include <linux/types.h>
 #include <linux/videodev2.h>])
 
+AC_CHECK_MEMBERS(m4_normalize([
+       struct v4l2_window.global_alpha,
+       struct v4l2_sdr_format.buffersize
+]),,, [#include <sys/time.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>])
+
 AC_CACHE_CHECK([for BLKGETSIZE64], [ac_cv_have_blkgetsize64],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
 #include <stdlib.h>
diff --git a/v4l2.c b/v4l2.c
index 637e8788a6b55fea133a9f95f5877bd572ddbb6b..ee833c1210560a747e7cf67ed75608db969516f4 100644 (file)
--- a/v4l2.c
+++ b/v4l2.c
@@ -30,6 +30,7 @@
 #include "defs.h"
 
 #include DEF_MPERS_TYPE(struct_v4l2_buffer)
+#include DEF_MPERS_TYPE(struct_v4l2_clip)
 #include DEF_MPERS_TYPE(struct_v4l2_create_buffers)
 #include DEF_MPERS_TYPE(struct_v4l2_ext_control)
 #include DEF_MPERS_TYPE(struct_v4l2_ext_controls)
@@ -44,6 +45,7 @@
 #include <linux/videodev2.h>
 
 typedef struct v4l2_buffer struct_v4l2_buffer;
+typedef struct v4l2_clip struct_v4l2_clip;
 typedef struct v4l2_create_buffers struct_v4l2_create_buffers;
 typedef struct v4l2_ext_control struct_v4l2_ext_control;
 typedef struct v4l2_ext_controls struct_v4l2_ext_controls;
@@ -200,10 +202,22 @@ print_v4l2_fmtdesc(struct tcb *const tcp, const kernel_ulong_t arg)
 
 #include "xlat/v4l2_fields.h"
 #include "xlat/v4l2_colorspaces.h"
+#include "xlat/v4l2_vbi_flags.h"
+#include "xlat/v4l2_sliced_flags.h"
 
-static void
-print_v4l2_format_fmt(const char *prefix, const struct_v4l2_format *f)
+static bool
+print_v4l2_clip(struct tcb *tcp, void *elem_buf, size_t elem_size, void* data)
+{
+       const struct_v4l2_clip *p = elem_buf;
+       tprintf(FMT_RECT, ARGS_RECT(p->c));
+       return true;
+}
+
+static bool
+print_v4l2_format_fmt(struct tcb *const tcp, const char *prefix,
+                     const struct_v4l2_format *f)
 {
+       bool ret = true;
        switch (f->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -244,42 +258,97 @@ print_v4l2_format_fmt(const char *prefix, const struct_v4l2_format *f)
                                f->fmt.pix_mp.plane_fmt[i].sizeimage,
                                f->fmt.pix_mp.plane_fmt[i].bytesperline);
                }
-               tprintf("], num_planes=%u}", (unsigned) f->fmt.pix_mp.num_planes);
+               tprintf("], num_planes=%u}",
+                       (unsigned) f->fmt.pix_mp.num_planes);
                break;
        }
 #endif
-
-       /* TODO: Complete this switch statement */
-#if 0
-       case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+       /* OUTPUT_OVERLAY since Linux v2.6.22-rc1~1118^2~179 */
 #if HAVE_DECL_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
 #endif
+       case V4L2_BUF_TYPE_VIDEO_OVERLAY: {
+               struct_v4l2_clip clip;
                tprints(prefix);
-               tprints("fmt.win={???}");
+               tprintf("fmt.win={left=%d, top=%d, width=%u, height=%u, field=",
+                       ARGS_RECT(f->fmt.win.w));
+               printxval(v4l2_fields, f->fmt.win.field, "V4L2_FIELD_???");
+               tprintf(", chromakey=%#x, clips=", f->fmt.win.chromakey);
+               ret = print_array(tcp, ptr_to_kulong(f->fmt.win.clips),
+                                 f->fmt.win.clipcount, &clip, sizeof(clip),
+                                 umoven_or_printaddr, print_v4l2_clip, 0);
+               tprintf(", clipcount=%u, bitmap=", f->fmt.win.clipcount);
+               printaddr(ptr_to_kulong(f->fmt.win.bitmap));
+#if HAVE_STRUCT_V4L2_WINDOW_GLOBAL_ALPHA
+               tprintf(", global_alpha=%#x", f->fmt.win.global_alpha);
+#endif
+               tprints("}");
                break;
-
+       }
        case V4L2_BUF_TYPE_VBI_CAPTURE:
        case V4L2_BUF_TYPE_VBI_OUTPUT:
                tprints(prefix);
-               tprints("fmt.vbi={???}");
+               tprintf("fmt.vbi={sampling_rate=%u, offset=%u, "
+                       "samples_per_line=%u, sample_format=",
+                       f->fmt.vbi.sampling_rate, f->fmt.vbi.offset,
+                       f->fmt.vbi.samples_per_line);
+               print_pixelformat(f->fmt.vbi.sample_format);
+               tprintf(", start=[%u, %u], count=[%u, %u], ",
+                       f->fmt.vbi.start[0], f->fmt.vbi.start[1],
+                       f->fmt.vbi.count[0], f->fmt.vbi.count[1]);
+               tprints("flags=");
+               printxval(v4l2_vbi_flags, f->fmt.vbi.flags, "V4L2_VBI_???");
+               tprints("}");
                break;
-
+       /* both since Linux v2.6.14-rc2~64 */
+#if HAVE_DECL_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
        case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-       case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+       case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: {
+               unsigned int i, j;
+
                tprints(prefix);
-               tprints("fmt.sliced={???}");
+               tprints("fmt.sliced={service_set=");
+               printxval(v4l2_sliced_flags, f->fmt.sliced.service_set,
+                       "V4L2_SLICED_???");
+               tprintf(", io_size=%u, service_lines=[",
+                       f->fmt.sliced.io_size);
+               for (i = 0; i < ARRAY_SIZE(f->fmt.sliced.service_lines); i++) {
+                       if (i > 0)
+                               tprints(", ");
+                       tprints("[");
+                       for (j = 0;
+                            j < ARRAY_SIZE(f->fmt.sliced.service_lines[0]);
+                            j++) {
+                               if (j > 0)
+                                       tprints(", ");
+                               tprintf("%#x",
+                                       f->fmt.sliced.service_lines[i][j]);
+                       }
+                       tprints("]");
+               }
+               tprints("]}");
                break;
-
+       }
+#endif
+       /* since Linux v4.4-rc1~118^2~14 */
+#if HAVE_DECL_V4L2_BUF_TYPE_SDR_OUTPUT
+       case V4L2_BUF_TYPE_SDR_OUTPUT:
+#endif
+       /* since Linux v3.15-rc1~85^2~213 */
 #if HAVE_DECL_V4L2_BUF_TYPE_SDR_CAPTURE
        case V4L2_BUF_TYPE_SDR_CAPTURE:
-       case V4L2_BUF_TYPE_SDR_OUTPUT:
                tprints(prefix);
-               tprints("fmt.sdr={???}");
-               break;
+               tprints("fmt.sdr={pixelformat=");
+               print_pixelformat(f->fmt.sdr.pixelformat);
+#if HAVE_STRUCT_V4L2_SDR_FORMAT_BUFFERSIZE
+               tprintf(", buffersize=%u",
+                       f->fmt.sdr.buffersize);
 #endif
+               tprints("}");
+               break;
 #endif
        }
+       return ret;
 }
 
 static int
@@ -296,11 +365,14 @@ print_v4l2_format(struct tcb *const tcp, const kernel_ulong_t arg,
                printxval(v4l2_buf_types, f.type, "V4L2_BUF_TYPE_???");
                if (is_get)
                        return 0;
-               print_v4l2_format_fmt(", ", &f);
+               if (!print_v4l2_format_fmt(tcp, ", ", &f)) {
+                       tprints("}");
+                       return RVAL_DECODED | 1;
+               }
        } else {
                if (!syserror(tcp) && !umove(tcp, arg, &f)) {
                        const char *delim = is_get ? ", " : " => ";
-                       print_v4l2_format_fmt(delim, &f);
+                       print_v4l2_format_fmt(tcp, delim, &f);
                }
                tprints("}");
        }
@@ -822,7 +894,7 @@ print_v4l2_create_buffers(struct tcb *const tcp, const kernel_ulong_t arg)
                tprints(", format={type=");
                printxval(v4l2_buf_types, b.format.type,
                          "V4L2_BUF_TYPE_???");
-               print_v4l2_format_fmt(", ",
+               print_v4l2_format_fmt(tcp, ", ",
                                      (struct_v4l2_format *) &b.format);
                tprints("}}");
                return 0;
diff --git a/xlat/v4l2_sliced_flags.in b/xlat/v4l2_sliced_flags.in
new file mode 100644 (file)
index 0000000..baff2e2
--- /dev/null
@@ -0,0 +1,6 @@
+V4L2_SLICED_TELETEXT_B
+V4L2_SLICED_VPS
+V4L2_SLICED_CAPTION_525
+V4L2_SLICED_WSS_625
+V4L2_SLICED_VBI_525
+V4L2_SLICED_VBI_625
diff --git a/xlat/v4l2_vbi_flags.in b/xlat/v4l2_vbi_flags.in
new file mode 100644 (file)
index 0000000..b367e60
--- /dev/null
@@ -0,0 +1,6 @@
+V4L2_VBI_UNSYNC
+V4L2_VBI_INTERLACED
+V4L2_VBI_ITU_525_F1_START
+V4L2_VBI_ITU_525_F2_START
+V4L2_VBI_ITU_625_F1_START
+V4L2_VBI_ITU_625_F2_START