From 51e65fcb751b46be797f6a5d01805aa0c5756c73 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 27 Jun 2011 14:25:10 +0200 Subject: [PATCH] v4l2-compliance: add VIDIOC_G_FBUF compliance test. Signed-off-by: Hans Verkuil --- utils/v4l2-compliance/fixme.txt | 7 ++++ utils/v4l2-compliance/v4l2-compliance.cpp | 7 +++- utils/v4l2-compliance/v4l2-compliance.h | 2 ++ utils/v4l2-compliance/v4l2-test-formats.cpp | 51 +++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/utils/v4l2-compliance/fixme.txt b/utils/v4l2-compliance/fixme.txt index 90ce9bf..d667392 100644 --- a/utils/v4l2-compliance/fixme.txt +++ b/utils/v4l2-compliance/fixme.txt @@ -22,3 +22,10 @@ here they won't be forgotten. - Control documentation is out of date regarding use of class_ctrl 0 and how error_idx should be set for G/S_EXT_CTRLS and for TRY_EXT_CTRLS (which does this slightly differently). + +- V4L2_FBUF_CAP_SRC_CHROMAKEY: I believe this is defined the wrong way around in + DocBook. + +- define properly V4L2_FBUF_FLAG_PRIMARY and V4L2_FBUF_FLAG_OVERLAY. +- ditto V4L2_FBUF_CAP_EXTERNOVERLAY: do bytesperline, sizeimage and base need to be + set or not? Determine for overlay and output overlay. diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index b711635..c0ce966 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -267,6 +267,10 @@ static int testCap(struct node *node) if (node->is_vbi && !(caps & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_VBI_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT))) return fail("vbi node without the relevant capabilities\n"); + // You can't have both set due to missing buffer type in VIDIOC_G/S_FBUF + fail_on_test((caps & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) == + (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)); + return 0; } @@ -582,12 +586,13 @@ int main(int argc, char **argv) printf("Format ioctls:\n"); printf("\ttest VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: %s\n", ok(testEnumFormats(&node))); + printf("\ttest VIDIOC_G_FBUF: %s\n", ok(testFBuf(&node))); printf("\ttest VIDIOC_G_FMT: %s\n", ok(testFormats(&node))); /* TODO: VIDIOC_CROPCAP, VIDIOC_G/S_CROP - VIDIOC_G/S_FBUF/OVERLAY + VIDIOC_S_FBUF/OVERLAY VIDIOC_S/TRY_FMT VIDIOC_G/S_PARM VIDIOC_G/S_JPEGCOMP diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h index dcd0aec..67adc78 100644 --- a/utils/v4l2-compliance/v4l2-compliance.h +++ b/utils/v4l2-compliance/v4l2-compliance.h @@ -57,6 +57,7 @@ struct node { unsigned std_controls; unsigned priv_controls; qctrl_list controls; + __u32 fbuf_caps; pixfmt_set buftype_pixfmts[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE + 1]; }; @@ -158,6 +159,7 @@ int testCustomTimings(struct node *node); // Format ioctl tests int testEnumFormats(struct node *node); +int testFBuf(struct node *node); int testFormats(struct node *node); #endif diff --git a/utils/v4l2-compliance/v4l2-test-formats.cpp b/utils/v4l2-compliance/v4l2-test-formats.cpp index 6fc23e2..976a3c9 100644 --- a/utils/v4l2-compliance/v4l2-test-formats.cpp +++ b/utils/v4l2-compliance/v4l2-test-formats.cpp @@ -308,6 +308,52 @@ int testEnumFormats(struct node *node) return 0; } +int testFBuf(struct node *node) +{ + struct v4l2_framebuffer fbuf; + struct v4l2_pix_format &fmt = fbuf.fmt; + __u32 caps; + __u32 flags; + int ret; + + memset(&fbuf, 0xff, sizeof(fbuf)); + fbuf.fmt.priv = 0; + ret = doioctl(node, VIDIOC_G_FBUF, &fbuf); + fail_on_test(ret == 0 && !(node->caps & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY))); + fail_on_test(ret == EINVAL && (node->caps & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY))); + if (ret == EINVAL) + return -ENOSYS; + if (ret) + return fail("expected EINVAL, but got %d when getting framebuffer format\n", ret); + node->fbuf_caps = caps = fbuf.capability; + flags = fbuf.flags; + if (node->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) + fail_on_test(!fbuf.base); + if (flags & V4L2_FBUF_FLAG_CHROMAKEY) + fail_on_test(!(caps & V4L2_FBUF_CAP_CHROMAKEY)); + if (flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) + fail_on_test(!(caps & V4L2_FBUF_CAP_LOCAL_ALPHA)); + if (flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) + fail_on_test(!(caps & V4L2_FBUF_CAP_GLOBAL_ALPHA)); + if (flags & V4L2_FBUF_FLAG_LOCAL_INV_ALPHA) + fail_on_test(!(caps & V4L2_FBUF_CAP_LOCAL_INV_ALPHA)); + if (flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) + fail_on_test(!(caps & V4L2_FBUF_CAP_SRC_CHROMAKEY)); + fail_on_test(!fmt.width || !fmt.height); + if (fmt.priv) + warn("fbuf.fmt.priv is non-zero\n"); + /* Not yet: unclear what EXTERNOVERLAY means in a output overlay context + if (caps & V4L2_FBUF_CAP_EXTERNOVERLAY) { + fail_on_test(fmt.bytesperline); + fail_on_test(fmt.sizeimage); + fail_on_test(fbuf.base); + }*/ + fail_on_test(fmt.bytesperline && fmt.bytesperline < fmt.width); + fail_on_test(fmt.sizeimage && fmt.sizeimage < fmt.bytesperline * fmt.height); + fail_on_test(!fmt.colorspace); + return 0; +} + static int testFormatsType(struct node *node, enum v4l2_buf_type type) { pixfmt_set &set = node->buftype_pixfmts[type]; @@ -403,11 +449,16 @@ static int testFormatsType(struct node *node, enum v4l2_buf_type type) win.field != V4L2_FIELD_TOP && win.field != V4L2_FIELD_BOTTOM && win.field != V4L2_FIELD_INTERLACED); + fail_on_test(win.clipcount && !(node->fbuf_caps & V4L2_FBUF_CAP_LIST_CLIPPING)); for (struct v4l2_clip *clip = win.clips; clip; win.clipcount--) { fail_on_test(clip == NULL); clip = clip->next; } fail_on_test(win.clipcount); + fail_on_test(win.chromakey && !(node->fbuf_caps & (V4L2_FBUF_CAP_CHROMAKEY | V4L2_FBUF_CAP_SRC_CHROMAKEY))); + if (!(node->fbuf_caps & V4L2_FBUF_CAP_BITMAP_CLIPPING)) + fail_on_test(win.bitmap); + fail_on_test(win.global_alpha && !(node->fbuf_caps & V4L2_FBUF_CAP_GLOBAL_ALPHA)); break; case V4L2_BUF_TYPE_PRIVATE: break; -- 2.7.4