This is an automatic generated email to let you know that the following patch were queued at the http://git.linuxtv.org/v4l-utils.git tree:
Subject: v4l2-compliance: add new test to verify if the format is really global. Author: Hans Verkuil <[email protected]> Date: Wed Sep 12 13:16:12 2012 +0200 When you change the format using VIDIOC_S_FMT and then read back the format with VIDIOC_G_FMT on another filehandle then the two formats should match, except for M2M devices where the format is actually per-filehandle. Many older drivers store the format in the filehandle, which is wrong. Signed-off-by: Hans Verkuil <[email protected]> (cherry picked from commit 2d1ea2e7fc304eb18267c2ced288368c94f85c46) Signed-off-by: Gregor Jasny <[email protected]> utils/v4l2-compliance/v4l2-test-formats.cpp | 153 ++++++++++++++++++++++++++- 1 files changed, 152 insertions(+), 1 deletions(-) --- http://git.linuxtv.org/v4l-utils.git?a=commitdiff;h=aa80bdc4053c7eea6a0cec38873567cd0161298b diff --git a/utils/v4l2-compliance/v4l2-test-formats.cpp b/utils/v4l2-compliance/v4l2-test-formats.cpp index e1e6292..477bc4d 100644 --- a/utils/v4l2-compliance/v4l2-test-formats.cpp +++ b/utils/v4l2-compliance/v4l2-test-formats.cpp @@ -583,6 +583,127 @@ int testTryFormats(struct node *node) return node->valid_buftypes ? 0 : ENOTTY; } +static int testGlobalFormat(struct node *node, int type) +{ + struct v4l2_fmtdesc fdesc; + struct v4l2_frmsizeenum fsize; + struct v4l2_format fmt1, fmt2; + struct v4l2_pix_format *p1 = &fmt1.fmt.pix; + struct v4l2_pix_format *p2 = &fmt2.fmt.pix; + struct v4l2_pix_format_mplane *mp1 = &fmt1.fmt.pix_mp; + struct v4l2_pix_format_mplane *mp2 = &fmt2.fmt.pix_mp; + __u32 pixfmt1, pixfmt2; + __u32 w1 = 0, w2 = 0, h1 = 0, h2 = 0; + + memset(&fmt1, 0, sizeof(fmt1)); + memset(&fmt2, 0, sizeof(fmt2)); + fmt1.type = fmt2.type = type; + fdesc.index = 1; + fdesc.type = type; + memset(&fsize, 0, sizeof(fsize)); + + if (!doioctl(node, VIDIOC_ENUM_FMT, &fdesc)) { + // We found at least two different formats. + pixfmt2 = fdesc.pixelformat; + fdesc.index = 0; + doioctl(node, VIDIOC_ENUM_FMT, &fdesc); + pixfmt1 = fdesc.pixelformat; + } else { + fdesc.index = 0; + doioctl(node, VIDIOC_ENUM_FMT, &fdesc); + fsize.pixel_format = fdesc.pixelformat; + if (doioctl(node, VIDIOC_ENUM_FRAMESIZES, &fsize)) + return 0; + pixfmt1 = pixfmt2 = fdesc.pixelformat; + switch (fsize.type) { + case V4L2_FRMSIZE_TYPE_CONTINUOUS: + case V4L2_FRMSIZE_TYPE_STEPWISE: + w1 = fsize.stepwise.min_width; + w2 = fsize.stepwise.max_width; + h1 = fsize.stepwise.min_height; + h2 = fsize.stepwise.max_height; + break; + case V4L2_FRMSIZE_TYPE_DISCRETE: + w1 = fsize.discrete.width; + h1 = fsize.discrete.height; + fsize.index = 1; + doioctl(node, VIDIOC_ENUM_FRAMESIZES, &fsize); + w2 = fsize.discrete.width; + h2 = fsize.discrete.height; + break; + } + } + // Check if we have found different formats, otherwise this + // test is pointless. + if (pixfmt1 == pixfmt2 && w1 == w2 && h1 == h2) + return 0; + + if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || + type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + mp1->pixelformat = pixfmt1; + mp1->width = w1; + mp1->height = h1; + mp2->pixelformat = pixfmt2; + mp2->width = w2; + mp2->height = h2; + } else { + p1->pixelformat = pixfmt1; + p1->width = w1; + p1->height = h1; + p2->pixelformat = pixfmt2; + p2->width = w2; + p2->height = h2; + } + if (doioctl(node, VIDIOC_S_FMT, &fmt1)) { + warn("Could not set fmt1\n"); + return 0; + } + if (doioctl(node->node2, VIDIOC_S_FMT, &fmt2)) { + warn("Could not set fmt1\n"); + return 0; + } + if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || + type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + if (mp1->pixelformat == mp2->pixelformat && + mp1->width == mp2->width && mp1->height == mp2->height) { + // This compliance test only succeeds if the two formats + // are really different after S_FMT + warn("Could not perform global format test\n"); + return 0; + } + } else { + if (p1->pixelformat == p2->pixelformat && + p1->width == p2->width && p1->height == p2->height) { + // This compliance test only succeeds if the two formats + // are really different after S_FMT + warn("Could not perform global format test\n"); + return 0; + } + } + doioctl(node, VIDIOC_G_FMT, &fmt1); + if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || + type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + pixfmt1 = mp1->pixelformat; + w1 = mp1->width; + h1 = mp1->height; + pixfmt2 = mp2->pixelformat; + w2 = mp2->width; + h2 = mp2->height; + } else { + pixfmt1 = p1->pixelformat; + w1 = p1->width; + h1 = p1->height; + pixfmt2 = p2->pixelformat; + w2 = p2->width; + h2 = p2->height; + } + if (pixfmt1 != pixfmt2 || w1 != w2 || h1 != h2) + return fail("Global format mismatch: %08x/%dx%d vs %08x/%dx%d\n", + pixfmt1, w1, h1, pixfmt2, w2, h2); + info("Global format check succeeded for type %d\n", type); + return 0; +} + int testSetFormats(struct node *node) { struct v4l2_format fmt, fmt_set; @@ -620,7 +741,37 @@ int testSetFormats(struct node *node) ret = doioctl(node, VIDIOC_S_FMT, &fmt); if (!ret) warn("Buffer type PRIVATE allowed!\n"); - return node->valid_buftypes ? 0 : ENOTTY; + if (!node->valid_buftypes) + return ENOTTY; + + // Test if setting a format on one fh will set the format for all + // filehandles. + if (node->node2 == NULL) + return 0; + // m2m devices are unique in that the format is often per-filehandle. + if (node->is_m2m) + return 0; + + for (type = 0; type <= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; type++) { + switch (type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + if (!(node->valid_buftypes & (1 << type))) + continue; + + ret = testGlobalFormat(node, type); + if (ret) + return ret; + break; + + default: + break; + } + } + + return 0; } static int testSlicedVBICapType(struct node *node, unsigned type) _______________________________________________ linuxtv-commits mailing list [email protected] http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits
