v4l2-compliance: improved v4l helpers header, add tracing
authorHans Verkuil <hans.verkuil@cisco.com>
Wed, 16 Jul 2014 06:03:57 +0000 (08:03 +0200)
committerHans Verkuil <hans.verkuil@cisco.com>
Wed, 16 Jul 2014 06:03:57 +0000 (08:03 +0200)
The v4l-helpers.h header was missing ioctl tracing capabilities, this was
fairly annoying. This has now been added.

Also added additional inlines for capability checks.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
utils/v4l2-compliance/v4l-helpers.h
utils/v4l2-compliance/v4l2-compliance.cpp
utils/v4l2-compliance/v4l2-compliance.h
utils/v4l2-compliance/v4l2-test-buffers.cpp

index e718a24..6eb0989 100644 (file)
@@ -8,12 +8,30 @@
 
 struct v4l_fd {
        int fd;
+       __u32 caps;
+       bool trace;
        int (*ioctl)(int fd, unsigned long cmd, ...);
        void *(*mmap)(void *addr, size_t length, int prot, int flags,
                      int fd, int64_t offset);
        int (*munmap)(void *addr, size_t length);
 };
 
+static inline int v4l_named_ioctl(struct v4l_fd *f, const char *cmd_name,
+               unsigned long cmd, void *arg)
+{
+       int retval;
+       int e;
+
+       errno = 0;
+       retval = f->ioctl(f->fd, cmd, arg);
+       e = errno;
+       if (f->trace)
+               fprintf(stderr, "\t\t%s returned %d (%s)\n", cmd_name, retval, strerror(e));
+       return retval ? e : 0;
+}
+
+#define v4l_ioctl(f, cmd, arg) v4l_named_ioctl(f, #cmd, cmd, arg)
+
 /*
  * mmap has a different prototype compared to v4l2_mmap. Because of
  * this we have to make a wrapper for it.
@@ -24,36 +42,170 @@ static inline void *v4l_fd_mmap(void *addr, size_t length, int prot, int flags,
        return mmap(addr, length, prot, flags, fd, offset);
 }
 
+static inline void *v4l_mmap(struct v4l_fd *f, size_t length, off_t offset)
+{
+       return f->mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, f->fd, offset);
+}
+
+static inline int v4l_munmap(struct v4l_fd *f, void *start, size_t length)
+{
+       return f->munmap(start, length) ? errno : 0;
+}
+
+static inline int v4l_querycap(struct v4l_fd *f, struct v4l2_capability *cap)
+{
+       return v4l_ioctl(f, VIDIOC_QUERYCAP, cap);
+}
+
+static inline __u32 v4l_capability_g_caps(const struct v4l2_capability *cap)
+{
+       return (cap->capabilities & V4L2_CAP_DEVICE_CAPS) ?
+                       cap->device_caps : cap->capabilities;
+}
+
+static inline __u32 v4l_g_caps(struct v4l_fd *f)
+{
+       return f->caps;
+}
+
+static inline bool v4l_has_vid_cap(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE);
+}
+
+static inline bool v4l_has_vid_out(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE);
+}
+
+static inline bool v4l_has_vid_m2m(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & (V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE);
+}
+
+static inline bool v4l_has_overlay_cap(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_VIDEO_OVERLAY;
+}
+
+static inline bool v4l_has_overlay_out(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
+}
+
+static inline bool v4l_has_raw_vbi_cap(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_VBI_CAPTURE;
+}
+
+static inline bool v4l_has_sliced_vbi_cap(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_SLICED_VBI_CAPTURE;
+}
+
+static inline bool v4l_has_vbi_cap(struct v4l_fd *f)
+{
+       return v4l_has_raw_vbi_cap(f) || v4l_has_sliced_vbi_cap(f);
+}
+
+static inline bool v4l_has_raw_vbi_out(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_VBI_OUTPUT;
+}
+
+static inline bool v4l_has_sliced_vbi_out(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_SLICED_VBI_OUTPUT;
+}
+
+static inline bool v4l_has_vbi_out(struct v4l_fd *f)
+{
+       return v4l_has_raw_vbi_out(f) || v4l_has_sliced_vbi_out(f);
+}
+
+static inline bool v4l_has_radio_rx(struct v4l_fd *f)
+{
+       return (v4l_g_caps(f) & V4L2_CAP_RADIO) &&
+              (v4l_g_caps(f) & V4L2_CAP_TUNER);
+}
+
+static inline bool v4l_has_radio_tx(struct v4l_fd *f)
+{
+       return (v4l_g_caps(f) & V4L2_CAP_RADIO) &&
+              (v4l_g_caps(f) & V4L2_CAP_MODULATOR);
+}
+
+static inline bool v4l_has_rds_cap(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_RDS_CAPTURE;
+}
+
+static inline bool v4l_has_rds_out(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_RDS_OUTPUT;
+}
+
+static inline bool v4l_has_sdr_cap(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_SDR_CAPTURE;
+}
+
+static inline bool v4l_has_hwseek(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_HW_FREQ_SEEK;
+}
+
+static inline bool v4l_has_rw(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_READWRITE;
+}
+
+static inline bool v4l_has_streaming(struct v4l_fd *f)
+{
+       return v4l_g_caps(f) & V4L2_CAP_STREAMING;
+}
+
 static inline void v4l_fd_init(struct v4l_fd *f, int fd)
 {
+       struct v4l2_capability cap;
+
        f->fd = fd;
        f->ioctl = ioctl;
        f->mmap = v4l_fd_mmap;
        f->munmap = munmap;
-}
-
-#define v4l_fd_libv4l2_init(f, fd)             \
-       do {                                    \
-               (f)->fd = fd;                   \
-               (f)->ioctl = v4l2_ioctl;        \
-               (f)->mmap = v4l2_mmap;          \
-               (f)->munmap = v4l2_munmap;      \
+       f->caps = v4l_querycap(f, &cap) ? 0 : v4l_capability_g_caps(&cap);
+}
+
+#define v4l_fd_libv4l2_init(f, fd)                     \
+       do {                                            \
+               struct v4l2_capability cap;             \
+                                                       \
+               (f)->fd = fd;                           \
+               (f)->ioctl = v4l2_ioctl;                \
+               (f)->mmap = v4l2_mmap;                  \
+               (f)->munmap = v4l2_munmap;              \
+               (f)->caps = v4l_querycap(f, &cap) ? 0 : \
+                       v4l_capability_g_caps(&cap);    \
        } while (0)
 
-static inline int v4l_ioctl(struct v4l_fd *f, unsigned long cmd, void *arg)
+static inline __u32 v4l_buf_type_g_vid_cap(struct v4l_fd *f)
 {
-       return f->ioctl(f->fd, cmd, arg) ? errno : 0;
+       if (v4l_g_caps(f) & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_M2M))
+               return V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       if (v4l_g_caps(f) & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
+               return V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+       return 0;
 }
 
-static inline void *v4l_mmap(struct v4l_fd *f, size_t length, off_t offset)
+static inline __u32 v4l_buf_type_g_vid_out(struct v4l_fd *f)
 {
-       return f->mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, f->fd, offset);
+       if (f->caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_M2M))
+               return V4L2_BUF_TYPE_VIDEO_OUTPUT;
+       if (f->caps & (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
+               return V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+       return 0;
 }
 
-static inline int v4l_munmap(struct v4l_fd *f, void *start, size_t length)
-{
-       return f->munmap(start, length) ? errno : 0;
-}
 
 static inline bool v4l_buf_type_is_planar(unsigned type)
 {
@@ -83,7 +235,7 @@ static inline bool v4l_buf_type_is_video(unsigned type)
        }
 }
 
-static inline bool v4l_buf_type_is_vbi(unsigned type)
+static inline bool v4l_buf_type_is_raw_vbi(unsigned type)
 {
        return type == V4L2_BUF_TYPE_VBI_CAPTURE ||
               type == V4L2_BUF_TYPE_VBI_OUTPUT;
@@ -95,6 +247,11 @@ static inline bool v4l_buf_type_is_sliced_vbi(unsigned type)
               type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
 }
 
+static inline bool v4l_buf_type_is_vbi(unsigned type)
+{
+       return v4l_buf_type_is_raw_vbi(type) || v4l_buf_type_is_sliced_vbi(type);
+}
+
 static inline bool v4l_buf_type_is_overlay(unsigned type)
 {
        return type == V4L2_BUF_TYPE_VIDEO_OVERLAY ||
@@ -106,24 +263,6 @@ static inline bool v4l_buf_type_is_sdr(unsigned type)
        return type == V4L2_BUF_TYPE_SDR_CAPTURE;
 }
 
-static inline int v4l_querycap(struct v4l_fd *f, struct v4l2_capability *cap)
-{
-       return v4l_ioctl(f, VIDIOC_QUERYCAP, cap);
-}
-
-static inline __u32 v4l_capability_g_caps(const struct v4l2_capability *cap)
-{
-       return (cap->capabilities & V4L2_CAP_DEVICE_CAPS) ?
-                       cap->device_caps : cap->capabilities;
-}
-
-static inline __u32 v4l_querycap_g_caps(struct v4l_fd *f)
-{
-       struct v4l2_capability cap;
-
-       return v4l_querycap(f, &cap) ? 0 : v4l_capability_g_caps(&cap);
-}
-
 static inline int v4l_g_fmt(struct v4l_fd *f, struct v4l2_format *fmt, unsigned type)
 {
        fmt->type = type;
@@ -849,7 +988,7 @@ static inline int v4l_queue_create_bufs(struct v4l_fd *f,
        if (fmt) {
                createbufs.format = *fmt;
        } else {
-               ret = v4l_ioctl(f, VIDIOC_G_FMT, &createbufs.format);
+               ret = v4l_g_fmt(f, &createbufs.format, q->type);
                if (ret)
                        return ret;
        }
index a4ee9a1..0ddfba2 100644 (file)
@@ -131,23 +131,24 @@ static void usage(void)
 
 static void v4l_fd_test_init(struct v4l_fd *f, int fd)
 {
+       struct v4l2_capability cap;
+
        f->fd = fd;
        f->ioctl = test_ioctl;
        f->mmap = test_mmap;
        f->munmap = test_munmap;
+       f->trace = options[OptTrace];
+       f->caps = v4l_querycap(f, &cap) ? 0 : v4l_capability_g_caps(&cap);
 }
 
 int doioctl_name(struct node *node, unsigned long int request, void *parm,
-                const char *name, bool no_wrapper)
+                const char *name)
 {
        int retval;
        int e;
 
        errno = 0;
-       if (no_wrapper)
-               retval = ioctl(node->vfd.fd, request, parm);
-       else
-               retval = test_ioctl(node->vfd.fd, request, parm);
+       retval = test_ioctl(node->vfd.fd, request, parm);
        e = errno;
        if (options[OptTrace])
                printf("\t\t%s returned %d (%s)\n", name, retval, strerror(e));
index 2b47f30..ade9d4b 100644 (file)
@@ -184,9 +184,8 @@ static inline double fract2f(const struct v4l2_fract *f)
 }
 
 int doioctl_name(struct node *node, unsigned long int request, void *parm,
-                const char *name, bool no_wrapper = false);
+                const char *name);
 #define doioctl(n, r, p) doioctl_name(n, r, p, #r)
-#define doioctl_no_wrap(n, r, p) doioctl_name(n, r, p, #r, true)
 
 std::string cap2s(unsigned cap);
 std::string buftype2s(int type);
index f5e5c77..e7afe66 100644 (file)
@@ -631,6 +631,8 @@ static int captureBufs(struct node *node, const queue &q,
                                printf("\r\t%s: Frame #%03d%s",
                                                buftype2s(q.g_type()).c_str(),
                                                frame_count - count, use_poll ? " (polling)" : "");
+                               if (node->vfd.trace)
+                                       printf("\n");
                                fflush(stdout);
                        }
                        if (buf.is_capture() && node->is_m2m && buf.ts_is_copy()) {