From: Hans Verkuil Date: Wed, 16 Jul 2014 06:03:57 +0000 (+0200) Subject: v4l2-compliance: improved v4l helpers header, add tracing X-Git-Tag: v4l-utils-1.3.90~108 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0033599d67f5bfa2d11b9a09d9a77d9562d69850;p=platform%2Fupstream%2Fv4l-utils.git v4l2-compliance: improved v4l helpers header, add tracing 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 --- diff --git a/utils/v4l2-compliance/v4l-helpers.h b/utils/v4l2-compliance/v4l-helpers.h index e718a24..6eb0989 100644 --- a/utils/v4l2-compliance/v4l-helpers.h +++ b/utils/v4l2-compliance/v4l-helpers.h @@ -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; } diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index a4ee9a1..0ddfba2 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -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)); diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h index 2b47f30..ade9d4b 100644 --- a/utils/v4l2-compliance/v4l2-compliance.h +++ b/utils/v4l2-compliance/v4l2-compliance.h @@ -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); diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp index f5e5c77..e7afe66 100644 --- a/utils/v4l2-compliance/v4l2-test-buffers.cpp +++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp @@ -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()) {