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 capability checks, start on STD testing Author: Hans Verkuil <hverk...@xs4all.nl> Date: Sun Jan 16 18:21:37 2011 +0100 Signed-off-by: Hans Verkuil <hverk...@xs4all.nl> utils/v4l2-compliance/Makefile | 2 +- utils/v4l2-compliance/v4l2-compliance.cpp | 197 ++++++++++----------- utils/v4l2-compliance/v4l2-compliance.h | 7 + utils/v4l2-compliance/v4l2-test-input-output.cpp | 38 ++++ utils/v4l2-compliance/v4l2-test-io-config.cpp | 37 ++++ 5 files changed, 177 insertions(+), 104 deletions(-) --- http://git.linuxtv.org/v4l-utils.git?a=commitdiff;h=f061bba7c77d92ca4542248b6d101188674c8766 diff --git a/utils/v4l2-compliance/Makefile b/utils/v4l2-compliance/Makefile index c201dc0..c6798f1 100644 --- a/utils/v4l2-compliance/Makefile +++ b/utils/v4l2-compliance/Makefile @@ -5,7 +5,7 @@ all: $(TARGETS) -include *.d v4l2-compliance: v4l2-compliance.o v4l2-test-debug.o v4l2-test-input-output.o \ - v4l2-test-controls.o + v4l2-test-controls.o v4l2-test-io-config.o $(CXX) -I../../lib/include -I../../include $(LDFLAGS) -L../../lib/libv4l2 -lv4l2 -o $@ $^ install: $(TARGETS) diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index e947b7e..03a4cf9 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -55,18 +55,6 @@ enum Option { OptLast = 256 }; -enum Test { - TestRequired = 0, - TestMultipleOpen, - TestDebug, - TestInput, - TestOutput, - TestControls, - TestMax -}; - -static int test[TestMax]; - static char options[OptLast]; static int app_result; @@ -86,7 +74,6 @@ static struct option long_options[] = { {"verbose", no_argument, 0, OptVerbose}, {"trace", no_argument, 0, OptTrace}, {"wrapper", no_argument, 0, OptUseWrapper}, - {"test", required_argument, 0, OptTest}, {0, 0, 0, 0} }; @@ -102,9 +89,6 @@ static void usage(void) printf(" -V, --vbi-device=<dev> use device <dev> as the vbi device\n"); printf(" if <dev> is a single digit, then /dev/vbi<dev> is used\n"); printf(" -h, --help display this help message\n"); - printf(" -t, --test=<num> run specified test.\n"); - printf(" By default all tests are run.\n"); - printf(" 0 = test VIDIOC_QUERYCAP\n"); printf(" -v, --verbose turn on verbose reporting.\n"); printf(" -T, --trace trace all called ioctls.\n"); printf(" -w, --wrapper use the libv4l2 wrapper library.\n"); @@ -239,6 +223,14 @@ static int testCap(struct node *node) caps = vcap.capabilities; if (caps == 0) return fail("no capabilities set\n"); + if (node->is_video && !(caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | + V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY))) + return fail("video node without the relevant capabilities\n"); + if (node->is_radio && !(caps & (V4L2_CAP_RADIO | V4L2_CAP_MODULATOR))) + return fail("radio node without the relevant capabilities\n"); + 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"); return 0; } @@ -290,7 +282,6 @@ static int testPrio(struct node *node, struct node *node2) int main(int argc, char **argv) { int i; - unsigned t; struct node node = { -1 }; struct node video_node = { -1 }; struct node video_node2 = { -1 }; @@ -308,7 +299,6 @@ int main(int argc, char **argv) struct v4l2_capability vcap; /* list_cap */ char short_options[26 * 2 * 2 + 1]; int idx = 0; - int tests = 0; for (i = 0; long_options[i].name; i++) { if (!isalpha(long_options[i].val)) @@ -331,14 +321,6 @@ int main(int argc, char **argv) case OptHelp: usage(); return 0; - case OptTest: - t = strtoul(optarg, NULL, 0); - - if (t >= TestMax) - usage(); - test[t] = 1; - tests++; - break; case OptSetDevice: video_device = optarg; if (video_device[0] >= '0' && video_device[0] <= '9' && video_device[1] == 0) { @@ -390,10 +372,6 @@ int main(int argc, char **argv) return 1; } verbose = options[OptVerbose]; - if (!tests) { - for (t = 0; t < TestMax; t++) - test[t] = 1; - } wrapper = options[OptUseWrapper]; if (!video_device && !radio_device && !vbi_device) @@ -420,6 +398,7 @@ int main(int argc, char **argv) if (video_node.fd >= 0) { node.fd = video_node.fd; device = video_device; + node.is_video = true; } else if (radio_node.fd >= 0) { node.fd = radio_node.fd; device = radio_device; @@ -427,10 +406,19 @@ int main(int argc, char **argv) } else if (vbi_node.fd >= 0) { node.fd = vbi_node.fd; device = vbi_device; + node.is_vbi = true; } doioctl(&node, VIDIOC_QUERYCAP, &vcap); node.caps = vcap.capabilities; + if (node.caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | + V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_RDS_CAPTURE | + V4L2_CAP_RADIO | V4L2_CAP_TUNER)) + node.has_inputs = true; + if (node.caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VBI_OUTPUT | + V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_RDS_OUTPUT | + V4L2_CAP_MODULATOR)) + node.has_outputs = true; /* Information Opts */ @@ -448,88 +436,91 @@ int main(int argc, char **argv) printf("\nCompliance test for device %s (%susing libv4l2):\n\n", device, wrapper ? "" : "not "); - if (test[TestRequired]) { - printf("Required ioctls:\n"); - if (video_device) - printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&video_node))); - if (radio_device) - printf("\ttest VIDIOC_QUERYCAP for radio: %s\n", ok(testCap(&radio_node))); - if (vbi_device) - printf("\ttest VIDIOC_QUERYCAP for vbi: %s\n", ok(testCap(&vbi_node))); - printf("\n"); - } + /* Required ioctls */ - if (test[TestMultipleOpen]) { - printf("Allow for multiple opens:\n"); - if (video_device) { - printf("\ttest second video open: %s\n", - ok((video_node2.fd = test_open(video_device, O_RDWR)) < 0)); - if (video_node2.fd >= 0) { - printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&video_node2))); - printf("\ttest VIDIOC_S_PRIORITY: %s\n", - ok(testPrio(&video_node, &video_node2))); - test_close(video_node2.fd); - } + printf("Required ioctls:\n"); + printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&node))); + printf("\n"); + + /* Multiple opens */ + + printf("Allow for multiple opens:\n"); + if (video_device) { + printf("\ttest second video open: %s\n", + ok((video_node2.fd = test_open(video_device, O_RDWR)) < 0)); + if (video_node2.fd >= 0) { + printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&video_node2))); + printf("\ttest VIDIOC_S_PRIORITY: %s\n", + ok(testPrio(&video_node, &video_node2))); + test_close(video_node2.fd); } - if (radio_device) { - printf("\ttest second radio open: %s\n", - ok((radio_node2.fd = test_open(radio_device, O_RDWR)) < 0)); - if (radio_node2.fd >= 0) { - printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&radio_node2))); - printf("\ttest VIDIOC_S_PRIORITY: %s\n", - ok(testPrio(&radio_node, &radio_node2))); - test_close(radio_node2.fd); - } + } + if (radio_device) { + printf("\ttest second radio open: %s\n", + ok((radio_node2.fd = test_open(radio_device, O_RDWR)) < 0)); + if (radio_node2.fd >= 0) { + printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&radio_node2))); + printf("\ttest VIDIOC_S_PRIORITY: %s\n", + ok(testPrio(&radio_node, &radio_node2))); + test_close(radio_node2.fd); } - if (vbi_device) { - printf("\ttest second vbi open: %s\n", - ok((vbi_node2.fd = test_open(vbi_device, O_RDWR)) < 0)); - if (vbi_node2.fd >= 0) { - printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&vbi_node2))); - printf("\ttest VIDIOC_S_PRIORITY: %s\n", - ok(testPrio(&vbi_node, &vbi_node2))); - test_close(vbi_node2.fd); - } + } + if (vbi_device) { + printf("\ttest second vbi open: %s\n", + ok((vbi_node2.fd = test_open(vbi_device, O_RDWR)) < 0)); + if (vbi_node2.fd >= 0) { + printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&vbi_node2))); + printf("\ttest VIDIOC_S_PRIORITY: %s\n", + ok(testPrio(&vbi_node, &vbi_node2))); + test_close(vbi_node2.fd); } - printf("\n"); } + printf("\n"); - if (test[TestDebug]) { - printf("Debug ioctls:\n"); - printf("\ttest VIDIOC_DBG_G_CHIP_IDENT: %s\n", ok(testChipIdent(&node))); - printf("\ttest VIDIOC_DBG_G/S_REGISTER: %s\n", ok(testRegister(&node))); - printf("\ttest VIDIOC_LOG_STATUS: %s\n", ok(testLogStatus(&node))); - printf("\n"); - } + /* Debug ioctls */ - if (test[TestInput]) { - printf("Input ioctls:\n"); - printf("\ttest VIDIOC_S/G_TUNER: %s\n", ok(testTuner(&node))); - printf("\ttest VIDIOC_S/G/ENUMAUDIO: %s\n", ok(testInputAudio(&node))); - printf("\ttest VIDIOC_G/S/ENUMINPUT: %s\n", ok(testInput(&node))); - printf("\tInputs: %d Audio Inputs: %d Tuners: %d\n", - node.inputs, node.audio_inputs, node.tuners); - printf("\n"); - } + printf("Debug ioctls:\n"); + printf("\ttest VIDIOC_DBG_G_CHIP_IDENT: %s\n", ok(testChipIdent(&node))); + printf("\ttest VIDIOC_DBG_G/S_REGISTER: %s\n", ok(testRegister(&node))); + printf("\ttest VIDIOC_LOG_STATUS: %s\n", ok(testLogStatus(&node))); + printf("\n"); - if (test[TestOutput]) { - printf("Output ioctls:\n"); - printf("\ttest VIDIOC_S/G_MODULATOR: %s\n", ok(testModulator(&node))); - printf("\ttest VIDIOC_S/G/ENUMAUDOUT: %s\n", ok(testOutputAudio(&node))); - printf("\ttest VIDIOC_G/S/ENUMOUTPUT: %s\n", ok(testOutput(&node))); - printf("\tOutputs: %d Audio Outputs: %d Modulators: %d\n", - node.outputs, node.audio_outputs, node.modulators); - printf("\n"); - } + /* Input ioctls */ - if (test[TestControls]) { - printf("Control ioctls:\n"); - printf("\ttest VIDIOC_QUERYCTRL/MENU: %s\n", ok(testQueryControls(&node))); - printf("\ttest VIDIOC_S/G_CTRL: %s\n", ok(testSimpleControls(&node))); - printf("\tStandard Controls: %d Private Controls: %d\n", - node.std_controls, node.priv_controls); - printf("\n"); - } + printf("Input ioctls:\n"); + printf("\ttest VIDIOC_S/G_TUNER: %s\n", ok(testTuner(&node))); + printf("\ttest VIDIOC_S/G/ENUMAUDIO: %s\n", ok(testInputAudio(&node))); + printf("\ttest VIDIOC_G/S/ENUMINPUT: %s\n", ok(testInput(&node))); + printf("\tInputs: %d Audio Inputs: %d Tuners: %d\n", + node.inputs, node.audio_inputs, node.tuners); + printf("\n"); + + /* Output ioctls */ + + printf("Output ioctls:\n"); + printf("\ttest VIDIOC_S/G_MODULATOR: %s\n", ok(testModulator(&node))); + printf("\ttest VIDIOC_S/G/ENUMAUDOUT: %s\n", ok(testOutputAudio(&node))); + printf("\ttest VIDIOC_G/S/ENUMOUTPUT: %s\n", ok(testOutput(&node))); + printf("\tOutputs: %d Audio Outputs: %d Modulators: %d\n", + node.outputs, node.audio_outputs, node.modulators); + printf("\n"); + + /* Control ioctls */ + + printf("Control ioctls:\n"); + printf("\ttest VIDIOC_QUERYCTRL/MENU: %s\n", ok(testQueryControls(&node))); + printf("\ttest VIDIOC_S/G_CTRL: %s\n", ok(testSimpleControls(&node))); + printf("\tStandard Controls: %d Private Controls: %d\n", + node.std_controls, node.priv_controls); + printf("\n"); + + /* I/O configuration ioctls */ + + printf("Input/Output configuration ioctls:\n"); + printf("\ttest VIDIOC_ENUM/S/G/QUERY_STD: %s\n", ok(testStd(&node))); + printf("\n"); + + /* Final test report */ test_close(node.fd); printf("Total: %d Succeeded: %d Failed: %d Warnings: %d\n", diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h index 1bd735a..3575f4d 100644 --- a/utils/v4l2-compliance/v4l2-compliance.h +++ b/utils/v4l2-compliance/v4l2-compliance.h @@ -39,8 +39,12 @@ typedef std::list<test_queryctrl> qctrl_list; struct node { int fd; + bool is_video; bool is_radio; + bool is_vbi; unsigned caps; + bool has_outputs; + bool has_inputs; unsigned tuners; unsigned modulators; unsigned inputs; @@ -114,4 +118,7 @@ int testOutputAudio(struct node *node); int testQueryControls(struct node *node); int testSimpleControls(struct node *node); +// I/O configuration ioctl tests +int testStd(struct node *node); + #endif diff --git a/utils/v4l2-compliance/v4l2-test-input-output.cpp b/utils/v4l2-compliance/v4l2-test-input-output.cpp index 8056bfd..b379e65 100644 --- a/utils/v4l2-compliance/v4l2-test-input-output.cpp +++ b/utils/v4l2-compliance/v4l2-test-input-output.cpp @@ -110,6 +110,7 @@ int testTuner(struct node *node) struct v4l2_tuner tuner; v4l2_std_id std; unsigned t = 0; + bool has_rds = false; int ret; if (doioctl(node, VIDIOC_G_STD, &std)) @@ -130,11 +131,21 @@ int testTuner(struct node *node) return fail("invalid tuner %d\n", t); t++; node->tuners++; + if (tuner.capability & V4L2_TUNER_CAP_RDS) + has_rds = true; } memset(&tuner, 0, sizeof(tuner)); tuner.index = t; if (doioctl(node, VIDIOC_S_TUNER, &tuner) != EINVAL) return fail("could set invalid tuner %d\n", t); + if (node->tuners && !(node->caps & V4L2_CAP_TUNER)) + return fail("tuners found, but no tuner capability set\n"); + if (!node->tuners && (node->caps & V4L2_CAP_TUNER)) + return fail("no tuners found, but tuner capability set\n"); + if (has_rds && !(node->caps & V4L2_CAP_RDS_CAPTURE)) + return fail("RDS tuner capability, but no RDS capture capability?\n"); + if (!has_rds && (node->caps & V4L2_CAP_RDS_CAPTURE)) + return fail("No RDS tuner capability, but RDS capture capability?\n"); return 0; } @@ -217,6 +228,10 @@ int testInput(struct node *node) return fail("could set input to invalid input %d\n", i); if (doioctl(node, VIDIOC_S_INPUT, &cur_input)) return fail("couldn't set input to the original input %d\n", cur_input); + if (node->inputs && !node->has_inputs) + return fail("inputs found, but no input capabilities set\n"); + if (!node->inputs && node->has_inputs) + return fail("no inputs found, but input capabilities set\n"); return 0; } @@ -265,6 +280,10 @@ int testInputAudio(struct node *node) input.mode = 0; if (doioctl(node, VIDIOC_S_AUDIO, &input) != EINVAL) return fail("can set invalid audio input\n"); + if (node->audio_inputs && !(node->caps & V4L2_CAP_AUDIO)) + return fail("audio inputs reported, but no CAP_AUDIO set\n"); + if (node->audio_inputs == 0 && (node->caps & V4L2_CAP_AUDIO)) + return fail("no audio inputs reported, but CAP_AUDIO set\n"); memset(&input, 0xff, sizeof(input)); ret = doioctl(node, VIDIOC_G_AUDIO, &input); if (i == 0) { @@ -319,6 +338,7 @@ int testModulator(struct node *node) { struct v4l2_modulator mod; unsigned m = 0; + bool has_rds = false; int ret; for (;;) { @@ -338,11 +358,21 @@ int testModulator(struct node *node) return fail("cannot set modulator %d\n", m); m++; node->modulators++; + if (mod.capability & V4L2_TUNER_CAP_RDS) + has_rds = true; } memset(&mod, 0, sizeof(mod)); mod.index = m; if (doioctl(node, VIDIOC_S_MODULATOR, &mod) != EINVAL) return fail("could set invalid modulator %d\n", m); + if (node->modulators && !(node->caps & V4L2_CAP_MODULATOR)) + return fail("modulators found, but no modulator capability set\n"); + if (!node->modulators && (node->caps & V4L2_CAP_MODULATOR)) + return fail("no modulators found, but modulator capability set\n"); + if (has_rds && !(node->caps & V4L2_CAP_RDS_OUTPUT)) + return fail("RDS modulator capability, but no RDS output capability?\n"); + if (!has_rds && (node->caps & V4L2_CAP_RDS_OUTPUT)) + return fail("No RDS modulator capability, but RDS output capability?\n"); return 0; } @@ -419,6 +449,10 @@ int testOutput(struct node *node) return fail("could set output to invalid output %d\n", o); if (doioctl(node, VIDIOC_S_OUTPUT, &cur_output)) return fail("couldn't set output to the original output %d\n", cur_output); + if (node->outputs && !node->has_outputs) + return fail("outputs found, but no output capabilities set\n"); + if (!node->outputs && node->has_outputs) + return fail("no outputs found, but output capabilities set\n"); return 0; } @@ -465,6 +499,10 @@ int testOutputAudio(struct node *node) output.mode = 0; if (doioctl(node, VIDIOC_S_AUDOUT, &output) != EINVAL) return fail("can set invalid audio output\n"); + if (node->audio_outputs && !(node->caps & V4L2_CAP_AUDIO)) + return fail("audio outputs reported, but no CAP_AUDIO set\n"); + if (node->audio_outputs == 0 && (node->caps & V4L2_CAP_AUDIO)) + return fail("no audio outputs reported, but CAP_AUDIO set\n"); memset(&output, 0xff, sizeof(output)); ret = doioctl(node, VIDIOC_G_AUDOUT, &output); if (o == 0) { diff --git a/utils/v4l2-compliance/v4l2-test-io-config.cpp b/utils/v4l2-compliance/v4l2-test-io-config.cpp new file mode 100644 index 0000000..9bce007 --- /dev/null +++ b/utils/v4l2-compliance/v4l2-test-io-config.cpp @@ -0,0 +1,37 @@ +/* + V4L2 API compliance input/output configuration ioctl tests. + + Copyright (C) 2011 Hans Verkuil <hverk...@xs4all.nl> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <ctype.h> +#include <errno.h> +#include <sys/ioctl.h> +#include "v4l2-compliance.h" + +int testStd(struct node *node) +{ + return 0; +} _______________________________________________ linuxtv-commits mailing list linuxtv-commits@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits