From bff8857ce18f818fe2357a194ba6d8fc618db0cd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 16 Jul 2014 11:55:59 +0200 Subject: [PATCH] v4l2-compliance: fix problems with vbi streaming. VBI is only valid for SDTV inputs/outputs. In addition, when you start streaming make sure to call s_fmt with the right VBI type (raw vs sliced) otherwise streaming might not work if it is in the wrong mode. Signed-off-by: Hans Verkuil --- utils/v4l2-compliance/v4l-helpers.h | 34 +++++++++++++++++++ utils/v4l2-compliance/v4l2-compliance.cpp | 35 ++++++++++++-------- utils/v4l2-compliance/v4l2-test-buffers.cpp | 51 +++++++++++++++++++---------- 3 files changed, 89 insertions(+), 31 deletions(-) diff --git a/utils/v4l2-compliance/v4l-helpers.h b/utils/v4l2-compliance/v4l-helpers.h index 66b87f3..5567528 100644 --- a/utils/v4l2-compliance/v4l-helpers.h +++ b/utils/v4l2-compliance/v4l-helpers.h @@ -83,6 +83,13 @@ 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_vid_mplane(struct v4l_fd *f) +{ + return v4l_g_caps(f) & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | + 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; @@ -123,6 +130,11 @@ 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_vbi(struct v4l_fd *f) +{ + return v4l_has_vbi_cap(f) || v4l_has_vbi_out(f); +} + static inline bool v4l_has_radio_rx(struct v4l_fd *f) { return (v4l_g_caps(f) & V4L2_CAP_RADIO) && @@ -206,6 +218,28 @@ static inline __u32 v4l_buf_type_g_vid_out(struct v4l_fd *f) return 0; } +static inline __u32 v4l_g_buf_type(struct v4l_fd *f) +{ + if (v4l_has_vid_mplane(f)) + return v4l_has_vid_cap(f) ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + if (v4l_has_vid_cap(f)) + return V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (v4l_has_vid_out(f)) + return V4L2_BUF_TYPE_VIDEO_OUTPUT; + if (v4l_has_raw_vbi_cap(f)) + return V4L2_BUF_TYPE_VBI_CAPTURE; + if (v4l_has_sliced_vbi_cap(f)) + return V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; + if (v4l_has_raw_vbi_out(f)) + return V4L2_BUF_TYPE_VBI_OUTPUT; + if (v4l_has_sliced_vbi_out(f)) + return V4L2_BUF_TYPE_SLICED_VBI_OUTPUT; + if (v4l_has_sdr_cap(f)) + return V4L2_BUF_TYPE_SDR_CAPTURE; + return 0; +} + static inline bool v4l_buf_type_is_planar(unsigned type) { diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index 0ddfba2..98d00a7 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -428,6 +428,7 @@ static int testPrio(struct node *node, struct node *node2) static void streamingSetup(struct node *node) { struct v4l2_input input; + struct v4l2_output output; if (options[OptSetInput]) doioctl(node, VIDIOC_S_INPUT, &select_input); @@ -459,23 +460,31 @@ static void streamingSetup(struct node *node) doioctl(node, VIDIOC_S_FREQUENCY, &f); } - memset(&input, 0, sizeof(input)); - doioctl(node, VIDIOC_G_INPUT, &input.index); - doioctl(node, VIDIOC_ENUMINPUT, &input); + if (node->can_capture) { + memset(&input, 0, sizeof(input)); + doioctl(node, VIDIOC_G_INPUT, &input.index); + doioctl(node, VIDIOC_ENUMINPUT, &input); + node->cur_io_caps = input.capabilities; - if (input.capabilities & V4L2_IN_CAP_STD) { - v4l2_std_id std; + if (input.capabilities & V4L2_IN_CAP_STD) { + v4l2_std_id std; - doioctl(node, VIDIOC_QUERYSTD, &std); - if (std) - doioctl(node, VIDIOC_S_STD, &std); - } + doioctl(node, VIDIOC_QUERYSTD, &std); + if (std) + doioctl(node, VIDIOC_S_STD, &std); + } - if (input.capabilities & V4L2_IN_CAP_DV_TIMINGS) { - struct v4l2_dv_timings t; + if (input.capabilities & V4L2_IN_CAP_DV_TIMINGS) { + struct v4l2_dv_timings t; - if (doioctl(node, VIDIOC_QUERY_DV_TIMINGS, &t) == 0) - doioctl(node, VIDIOC_S_DV_TIMINGS, &t); + if (doioctl(node, VIDIOC_QUERY_DV_TIMINGS, &t) == 0) + doioctl(node, VIDIOC_S_DV_TIMINGS, &t); + } + } else { + memset(&output, 0, sizeof(output)); + doioctl(node, VIDIOC_G_OUTPUT, &output.index); + doioctl(node, VIDIOC_ENUMOUTPUT, &output); + node->cur_io_caps = output.capabilities; } } diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp index d4fbda7..1ccd66d 100644 --- a/utils/v4l2-compliance/v4l2-test-buffers.cpp +++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp @@ -364,6 +364,21 @@ static int testQueryBuf(struct node *node, unsigned type, unsigned count) return 0; } +static int testSetupVbi(struct node *node, int type) +{ + if (!v4l_buf_type_is_vbi(type)) + return 0; + + if (!(node->cur_io_caps & V4L2_IN_CAP_STD)) + return -1; + + cv4l_fmt vbi_fmt(&node->vfd, type); + + if (!vbi_fmt.g_fmt()) + vbi_fmt.s_fmt(); + return 0; +} + int testReqBufs(struct node *node) { bool can_stream = node->caps & V4L2_CAP_STREAMING; @@ -391,15 +406,8 @@ int testReqBufs(struct node *node) if (!(node->valid_buftypes & (1 << i))) continue; - switch (i) { - case V4L2_BUF_TYPE_VBI_CAPTURE: - case V4L2_BUF_TYPE_VBI_OUTPUT: - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (!(node->cur_io_caps & V4L2_IN_CAP_STD)) - continue; - break; - } + if (testSetupVbi(node, i)) + continue; info("test buftype %s\n", buftype2s(i).c_str()); if (node->valid_buftype == 0) @@ -523,15 +531,8 @@ int testExpBuf(struct node *node) if (v4l_buf_type_is_overlay(type)) continue; - switch (type) { - case V4L2_BUF_TYPE_VBI_CAPTURE: - case V4L2_BUF_TYPE_VBI_OUTPUT: - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (!(node->cur_io_caps & V4L2_IN_CAP_STD)) - continue; - break; - } + if (testSetupVbi(node, type)) + continue; queue q(node, type, V4L2_MEMORY_MMAP); @@ -555,6 +556,11 @@ int testReadWrite(struct node *node) char buf = 0; int ret; + if (v4l_has_vbi(&node->vfd) && + !(node->cur_io_caps & V4L2_IN_CAP_STD)) { + return 0; + } + fcntl(node->vfd.fd, F_SETFL, fd_flags | O_NONBLOCK); if (node->can_capture) ret = read(node->vfd.fd, &buf, 1); @@ -826,6 +832,9 @@ int testMmap(struct node *node, unsigned frame_count) queue q(node, type, V4L2_MEMORY_MMAP); queue m2m_q(node, invert_buf_type(type)); + + if (testSetupVbi(node, type)) + continue; ret = q.reqbufs(0); if (ret) { @@ -982,6 +991,9 @@ int testUserPtr(struct node *node, unsigned frame_count) queue q(node, type, V4L2_MEMORY_USERPTR); queue m2m_q(node, invert_buf_type(type)); + if (testSetupVbi(node, type)) + continue; + ret = q.reqbufs(0); if (ret) { fail_on_test(ret != EINVAL); @@ -1088,6 +1100,9 @@ int testDmaBuf(struct node *expbuf_node, struct node *node, unsigned frame_count queue m2m_q(node, invert_buf_type(type)); queue exp_q(expbuf_node, expbuf_type, V4L2_MEMORY_MMAP); + if (testSetupVbi(node, type)) + continue; + ret = q.reqbufs(0); if (ret) { fail_on_test(ret != EINVAL); -- 2.7.4