v4l2-compliance: fix problems with vbi streaming.
authorHans Verkuil <hans.verkuil@cisco.com>
Wed, 16 Jul 2014 09:55:59 +0000 (11:55 +0200)
committerHans Verkuil <hans.verkuil@cisco.com>
Wed, 16 Jul 2014 09:55:59 +0000 (11:55 +0200)
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 <hans.verkuil@cisco.com>
utils/v4l2-compliance/v4l-helpers.h
utils/v4l2-compliance/v4l2-compliance.cpp
utils/v4l2-compliance/v4l2-test-buffers.cpp

index 66b87f3..5567528 100644 (file)
@@ -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)
 {
index 0ddfba2..98d00a7 100644 (file)
@@ -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;
        }
 }
 
index d4fbda7..1ccd66d 100644 (file)
@@ -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);