int testEnumFormats(struct node *node) { static const __u32 buftype2cap[] = { 0, V4L2_CAP_VIDEO_CAPTURE, V4L2_CAP_VIDEO_OUTPUT, V4L2_CAP_VIDEO_OVERLAY, V4L2_CAP_VBI_CAPTURE, V4L2_CAP_VBI_OUTPUT, V4L2_CAP_SLICED_VBI_CAPTURE, V4L2_CAP_SLICED_VBI_OUTPUT, V4L2_CAP_VIDEO_OUTPUT_OVERLAY, V4L2_CAP_VIDEO_CAPTURE_MPLANE, V4L2_CAP_VIDEO_OUTPUT_MPLANE, }; int type; int ret; for (type = 0; type <= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; type++) { ret = testEnumFormatsType(node, (enum v4l2_buf_type)type); if (ret > 0) return ret; switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: case V4L2_BUF_TYPE_VIDEO_OVERLAY: case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: if (ret < 0 && (node->caps & buftype2cap[type])) return fail("%s cap set, but no %s formats defined\n", buftype2s(type).c_str(), buftype2s(type).c_str()); if (!ret && !(node->caps & buftype2cap[type])) return fail("%s cap not set, but %s formats defined\n", buftype2s(type).c_str(), buftype2s(type).c_str()); break; default: if (!ret) return fail("Buffer type %s not allowed!\n", buftype2s(type).c_str()); break; } } ret = testEnumFormatsType(node, V4L2_BUF_TYPE_PRIVATE); if (ret > 0) return ret; if (!ret) warn("Buffer type PRIVATE allowed!\n"); ret = testEnumFrameSizes(node, 0x20202020); if (ret >= 0) return fail("Accepted framesize for invalid format\n"); ret = testEnumFrameIntervals(node, 0x20202020, 640, 480, false); if (ret >= 0) return fail("Accepted frameinterval for invalid format\n"); return 0; }
static int testEnumFormatsType(struct node *node, unsigned type) { pixfmt_set &set = node->buftype_pixfmts[type]; struct v4l2_fmtdesc fmtdesc; unsigned f = 0; int ret; for (;;) { memset(&fmtdesc, 0xff, sizeof(fmtdesc)); fmtdesc.type = type; fmtdesc.index = f; ret = doioctl(node, VIDIOC_ENUM_FMT, &fmtdesc); if (ret == ENOTTY) return ret; if (f == 0 && ret == EINVAL) return ENOTTY; if (ret == EINVAL) break; if (ret) return fail("expected EINVAL, but got %d when enumerating buftype %d\n", ret, type); ret = check_0(fmtdesc.reserved, sizeof(fmtdesc.reserved)); if (ret) return fail("fmtdesc.reserved not zeroed\n"); if (fmtdesc.index != f) return fail("fmtdesc.index was modified\n"); if (fmtdesc.type != type) return fail("fmtdesc.type was modified\n"); ret = check_ustring(fmtdesc.description, sizeof(fmtdesc.description)); if (ret) return fail("fmtdesc.description not set\n"); if (!fmtdesc.pixelformat) return fail("fmtdesc.pixelformat not set\n"); if (!wrapper && (fmtdesc.flags & V4L2_FMT_FLAG_EMULATED)) return fail("drivers must never set the emulated flag\n"); if (fmtdesc.flags & ~(V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_EMULATED)) return fail("unknown flag %08x returned\n", fmtdesc.flags); ret = testEnumFrameSizes(node, fmtdesc.pixelformat); if (ret && ret != ENOTTY) return ret; if (ret == 0 && !(node->caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))) return fail("found framesizes when no video capture is supported\n"); f++; if (type == V4L2_BUF_TYPE_PRIVATE) continue; // Update array in v4l2-compliance.h if new buffer types are added assert(type <= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (set.find(fmtdesc.pixelformat) != set.end()) return fail("duplicate format %08x\n", fmtdesc.pixelformat); set.insert(fmtdesc.pixelformat); } info("found %d formats for buftype %d\n", f, type); return 0; }
int testEnumFormats(struct node *node) { bool supported = false; unsigned type; int ret; for (type = 0; type <= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; type++) { ret = testEnumFormatsType(node, type); if (ret && ret != ENOTTY) return ret; if (!ret) supported = true; switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: case V4L2_BUF_TYPE_VIDEO_OVERLAY: case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: if (ret && (node->caps & buftype2cap[type])) return fail("%s cap set, but no %s formats defined\n", buftype2s(type).c_str(), buftype2s(type).c_str()); if (!ret && !(node->caps & buftype2cap[type])) return fail("%s cap not set, but %s formats defined\n", buftype2s(type).c_str(), buftype2s(type).c_str()); break; default: if (!ret) return fail("Buffer type %s not allowed!\n", buftype2s(type).c_str()); break; } } ret = testEnumFormatsType(node, V4L2_BUF_TYPE_PRIVATE); if (ret && ret != ENOTTY) return ret; if (!ret) { supported = true; warn("Buffer type PRIVATE allowed!\n"); } ret = testEnumFrameSizes(node, 0x20202020); if (ret != ENOTTY) return fail("Accepted framesize for invalid format\n"); ret = testEnumFrameIntervals(node, 0x20202020, 640, 480, false); if (ret != ENOTTY) return fail("Accepted frameinterval for invalid format\n"); return supported ? 0 : ENOTTY; }