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 tuner/modulator tests. Author: Hans Verkuil <[email protected]> Date: Sat Jan 8 19:39:46 2011 +0100 Signed-off-by: Hans Verkuil <[email protected]> utils/v4l2-compliance/v4l2-compliance.cpp | 6 +- utils/v4l2-compliance/v4l2-compliance.h | 3 + utils/v4l2-compliance/v4l2-test-input-output.cpp | 260 ++++++++++++++++++---- 3 files changed, 224 insertions(+), 45 deletions(-) --- http://git.linuxtv.org/v4l-utils.git?a=commitdiff;h=3d0f100bde9a4ba2c37cac21afdca53e29df0e84 diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index 1e3661e..eee697f 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -283,8 +283,8 @@ int main(int argc, char **argv) struct node node = { -1 }; struct node video_node = { -1 }; struct node video_node2 = { -1 }; - struct node radio_node = { -1 }; - struct node radio_node2 = { -1 }; + struct node radio_node = { -1, true }; + struct node radio_node2 = { -1, true }; struct node vbi_node = { -1 }; struct node vbi_node2 = { -1 }; @@ -486,12 +486,14 @@ int main(int argc, char **argv) printf("Input ioctls:\n"); if (test[TestInput]) { + 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("Output ioctls:\n"); if (test[TestOutput]) { + 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))); } diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h index cbd7e7b..9a17c1b 100644 --- a/utils/v4l2-compliance/v4l2-compliance.h +++ b/utils/v4l2-compliance/v4l2-compliance.h @@ -29,6 +29,7 @@ extern unsigned caps; struct node { int fd; + bool is_radio; unsigned caps; unsigned tuners; unsigned modulators; @@ -58,10 +59,12 @@ int testRegister(struct node *node); int testLogStatus(struct node *node); // Input ioctl tests +int testTuner(struct node *node); int testInput(struct node *node); int testInputAudio(struct node *node); // Output ioctl tests +int testModulator(struct node *node); int testOutput(struct node *node); int testOutputAudio(struct node *node); diff --git a/utils/v4l2-compliance/v4l2-test-input-output.cpp b/utils/v4l2-compliance/v4l2-test-input-output.cpp index 6f9fabe..1cdd435 100644 --- a/utils/v4l2-compliance/v4l2-test-input-output.cpp +++ b/utils/v4l2-compliance/v4l2-test-input-output.cpp @@ -33,32 +33,139 @@ #define MAGIC 0x1eadbeef -static int validInput(const struct v4l2_input *descr, unsigned i, unsigned max_audio) +static int validTuner(struct node *node, const struct v4l2_tuner &tuner, + unsigned t, v4l2_std_id std) { - __u32 mask = (1 << max_audio) - 1; + bool valid_modes[5] = { true, false, false, true, false }; + bool tv = !node->is_radio; + enum v4l2_tuner_type type = tv ? V4L2_TUNER_ANALOG_TV : V4L2_TUNER_RADIO; + __u32 audmode; - if (descr->index != i) + if (tuner.index != t) return fail("invalid index\n"); - if (check_ustring(descr->name, sizeof(descr->name))) + if (check_ustring(tuner.name, sizeof(tuner.name))) return fail("invalid name\n"); - if (descr->type != V4L2_INPUT_TYPE_TUNER && descr->type != V4L2_INPUT_TYPE_CAMERA) + if (check_0(tuner.reserved, sizeof(tuner.reserved))) + return fail("non-zero reserved fields\n"); + if (tuner.type != type) + return fail("invalid tuner type %d\n", tuner.type); + if (tv && (tuner.capability & V4L2_TUNER_CAP_RDS)) + return fail("RDS for TV tuner?\n"); + if (!tv && (tuner.capability & (V4L2_TUNER_CAP_NORM | + V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2))) + return fail("TV capabilities for radio tuner?\n"); + if (tuner.rangelow >= tuner.rangehigh) + return fail("rangelow >= rangehigh\n"); + if (tuner.rangelow == 0 || tuner.rangehigh == 0xffffffff) + return fail("invalid rangelow or rangehigh\n"); + if (!(tuner.capability & V4L2_TUNER_CAP_STEREO) && + (tuner.rxsubchans & V4L2_TUNER_SUB_STEREO)) + return fail("stereo subchan, but no stereo caps?\n"); + if (!(tuner.capability & V4L2_TUNER_CAP_LANG1) && + (tuner.rxsubchans & V4L2_TUNER_SUB_LANG1)) + return fail("lang1 subchan, but no lang1 caps?\n"); + if (!(tuner.capability & V4L2_TUNER_CAP_LANG2) && + (tuner.rxsubchans & V4L2_TUNER_SUB_LANG2)) + return fail("lang2 subchan, but no lang2 caps?\n"); + if (!(tuner.capability & V4L2_TUNER_CAP_RDS) && + (tuner.rxsubchans & V4L2_TUNER_SUB_RDS)) + return fail("RDS subchan, but no RDS caps?\n"); + if (std == V4L2_STD_NTSC_M && (tuner.rxsubchans & V4L2_TUNER_SUB_LANG1)) + return fail("LANG1 subchan, but NTSC-M standard\n"); + if (tuner.audmode > V4L2_TUNER_MODE_LANG1_LANG2) + return fail("invalid audio mode\n"); + // Ambiguous whether this is allowed or not + // if (!tv && tuner.audmode > V4L2_TUNER_MODE_STEREO) + // return -16; + if (tuner.signal > 65535) + return fail("signal too large\n"); + if (tuner.capability & V4L2_TUNER_CAP_STEREO) + valid_modes[V4L2_TUNER_MODE_STEREO] = true; + if (tuner.capability & V4L2_TUNER_CAP_LANG2) { + valid_modes[V4L2_TUNER_MODE_LANG2] = true; + valid_modes[V4L2_TUNER_MODE_LANG1_LANG2] = true; + } + for (audmode = 0; audmode < 5; audmode++) { + struct v4l2_tuner tun = { 0 }; + + tun.index = tuner.index; + tun.audmode = audmode; + if (doioctl(node, VIDIOC_S_TUNER, &tun)) + return fail("cannot set audmode %d\n", audmode); + if (doioctl(node, VIDIOC_G_TUNER, &tun)) + fail("failure to get new tuner audmode\n"); + if (tun.audmode > V4L2_TUNER_MODE_LANG1_LANG2) + return fail("invalid new audmode\n"); + // Ambiguous whether this is allowed or not + // if (!tv && tun.audmode > V4L2_TUNER_MODE_STEREO) + // return -21; + // if (!valid_modes[tun.audmode]) + // return fail("accepted invalid audmode %d\n", audmode); + } + return 0; +} + +int testTuner(struct node *node) +{ + struct v4l2_tuner tuner; + v4l2_std_id std; + unsigned t = 0; + int ret; + + if (doioctl(node, VIDIOC_G_STD, &std)) + std = 0; + + for (;;) { + memset(&tuner, 0xff, sizeof(tuner)); + memset(tuner.reserved, 0, sizeof(tuner.reserved)); + tuner.index = t; + ret = doioctl(node, VIDIOC_G_TUNER, &tuner); + if (ret == EINVAL && t == 0) + return -ENOSYS; + if (ret == EINVAL) + break; + if (ret) + return fail("couldn't get tuner %d\n", t); + if (validTuner(node, tuner, t, std)) + return fail("invalid tuner %d\n", t); + t++; + node->tuners++; + } + 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); + return 0; +} + +static int validInput(struct node *node, const struct v4l2_input &descr, unsigned i) +{ + __u32 mask = (1 << node->audio_inputs) - 1; + + if (descr.index != i) + return fail("invalid index\n"); + if (check_ustring(descr.name, sizeof(descr.name))) + return fail("invalid name\n"); + if (descr.type != V4L2_INPUT_TYPE_TUNER && descr.type != V4L2_INPUT_TYPE_CAMERA) return fail("invalid type\n"); - if (descr->type == V4L2_INPUT_TYPE_CAMERA && descr->tuner) + if (descr.type == V4L2_INPUT_TYPE_CAMERA && descr.tuner) return fail("invalid tuner\n"); - if (!(descr->capabilities & V4L2_IN_CAP_STD) && descr->std) + if (!(descr.capabilities & V4L2_IN_CAP_STD) && descr.std) return fail("invalid std\n"); - if ((descr->capabilities & V4L2_IN_CAP_STD) && !descr->std) + if ((descr.capabilities & V4L2_IN_CAP_STD) && !descr.std) return fail("std == 0\n"); - if (descr->capabilities & ~0x7) + if (descr.capabilities & ~0x7) return fail("invalid capabilities\n"); - if (check_0(descr->reserved, sizeof(descr->reserved))) + if (check_0(descr.reserved, sizeof(descr.reserved))) return fail("non-zero reserved fields\n"); - if (descr->status & ~0x07070337) + if (descr.status & ~0x07070337) return fail("invalid status\n"); - if (descr->status & 0x02070000) + if (descr.status & 0x02070000) return fail("use of deprecated digital video status\n"); - if (descr->audioset & ~mask) + if (descr.audioset & ~mask) return fail("invalid audioset\n"); + if (descr.tuner && descr.tuner >= node->tuners) + return fail("invalid tuner\n"); return 0; } @@ -91,7 +198,7 @@ int testInput(struct node *node) return fail("could not set input to %d\n", i); if (input != i) return fail("input set to %d, but becomes %d?!\n", i, input); - if (validInput(&descr, i, node->audio_inputs)) + if (validInput(node, descr, i)) return fail("invalid attributes for input %d\n", i); for (a = 0; a <= node->audio_inputs; a++) { memset(&audio, 0, sizeof(audio)); @@ -112,19 +219,19 @@ int testInput(struct node *node) return 0; } -static int validInputAudio(const struct v4l2_audio *descr, unsigned i) +static int validInputAudio(const struct v4l2_audio &descr, unsigned i) { - if (descr->index != i) + if (descr.index != i) return fail("invalid index\n"); - if (check_ustring(descr->name, sizeof(descr->name))) + if (check_ustring(descr.name, sizeof(descr.name))) return fail("invalid name\n"); - if (descr->capability & ~0x3) + if (descr.capability & ~0x3) return fail("invalid capabilities\n"); - if (descr->mode != 0 && descr->mode != V4L2_AUDMODE_AVL) + if (descr.mode != 0 && descr.mode != V4L2_AUDMODE_AVL) return fail("invalid mode\n"); - if (!(descr->capability & V4L2_AUDCAP_AVL) && descr->mode) + if (!(descr.capability & V4L2_AUDCAP_AVL) && descr.mode) return fail("mode != 0\n"); - if (check_0(descr->reserved, sizeof(descr->reserved))) + if (check_0(descr.reserved, sizeof(descr.reserved))) return fail("non-zero reserved fields\n"); return 0; } @@ -146,7 +253,7 @@ int testInputAudio(struct node *node) break; if (ret) return fail("could not enumerate audio input %d\n", i); - if (validInputAudio(&input, i)) + if (validInputAudio(input, i)) return fail("invalid attributes for audio input %d\n", i); node->audio_inputs++; i++; @@ -168,33 +275,100 @@ int testInputAudio(struct node *node) return fail("cannot get current audio input\n"); if (input.index >= node->audio_inputs) return fail("invalid current audio input %d\n", input.index); - if (validInputAudio(&input, input.index)) + if (validInputAudio(input, input.index)) return fail("invalid attributes for audio input %d\n", input.index); return 0; } -static int validOutput(const struct v4l2_output *descr, unsigned o, unsigned max_audio) +static int validModulator(struct node *node, const struct v4l2_modulator &mod, unsigned m) { - __u32 mask = (1 << max_audio) - 1; + bool tv = !node->is_radio; - if (descr->index != o) + if (mod.index != m) return fail("invalid index\n"); - if (check_ustring(descr->name, sizeof(descr->name))) + if (check_ustring(mod.name, sizeof(mod.name))) return fail("invalid name\n"); - if (descr->type != V4L2_OUTPUT_TYPE_MODULATOR && descr->type != V4L2_OUTPUT_TYPE_ANALOG) + if (check_0(mod.reserved, sizeof(mod.reserved))) + return fail("non-zero reserved fields\n"); + if (tv && (mod.capability & V4L2_TUNER_CAP_RDS)) + return fail("RDS for TV modulator?\n"); + if (!tv && (mod.capability & (V4L2_TUNER_CAP_NORM | + V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2))) + return fail("TV capabilities for radio modulator?\n"); + if (mod.rangelow >= mod.rangehigh) + return fail("rangelow >= rangehigh\n"); + if (mod.rangelow == 0 || mod.rangehigh == 0xffffffff) + return fail("invalid rangelow or rangehigh\n"); + if (!(mod.capability & V4L2_TUNER_CAP_STEREO) && + (mod.txsubchans & V4L2_TUNER_SUB_STEREO)) + return fail("stereo subchan, but no stereo caps?\n"); + if (!(mod.capability & V4L2_TUNER_CAP_LANG1) && + (mod.txsubchans & V4L2_TUNER_SUB_LANG1)) + return fail("lang1 subchan, but no lang1 caps?\n"); + if (!(mod.capability & V4L2_TUNER_CAP_LANG2) && + (mod.txsubchans & V4L2_TUNER_SUB_LANG2)) + return fail("lang2 subchan, but no lang2 caps?\n"); + if (!(mod.capability & V4L2_TUNER_CAP_RDS) && + (mod.txsubchans & V4L2_TUNER_SUB_RDS)) + return fail("RDS subchan, but no RDS caps?\n"); + return 0; +} + +int testModulator(struct node *node) +{ + struct v4l2_modulator mod; + unsigned m = 0; + int ret; + + for (;;) { + memset(&mod, 0xff, sizeof(mod)); + memset(mod.reserved, 0, sizeof(mod.reserved)); + mod.index = m; + ret = doioctl(node, VIDIOC_G_MODULATOR, &mod); + if (ret == EINVAL && m == 0) + return -ENOSYS; + if (ret == EINVAL) + break; + if (ret) + return fail("couldn't get modulator %d\n", m); + if (validModulator(node, mod, m)) + return fail("invalid modulator %d\n", m); + if (doioctl(node, VIDIOC_S_MODULATOR, &mod)) + return fail("cannot set modulator %d\n", m); + m++; + node->modulators++; + } + 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); + return 0; +} + +static int validOutput(struct node *node, const struct v4l2_output &descr, unsigned o) +{ + __u32 mask = (1 << node->audio_outputs) - 1; + + if (descr.index != o) + return fail("invalid index\n"); + if (check_ustring(descr.name, sizeof(descr.name))) + return fail("invalid name\n"); + if (descr.type != V4L2_OUTPUT_TYPE_MODULATOR && descr.type != V4L2_OUTPUT_TYPE_ANALOG) return fail("invalid type\n"); - if (descr->type == V4L2_OUTPUT_TYPE_ANALOG && descr->modulator) + if (descr.type == V4L2_OUTPUT_TYPE_ANALOG && descr.modulator) return fail("invalid modulator\n"); - if (!(descr->capabilities & V4L2_OUT_CAP_STD) && descr->std) + if (!(descr.capabilities & V4L2_OUT_CAP_STD) && descr.std) return fail("invalid std\n"); - if ((descr->capabilities & V4L2_OUT_CAP_STD) && !descr->std) + if ((descr.capabilities & V4L2_OUT_CAP_STD) && !descr.std) return fail("std == 0\n"); - if (descr->capabilities & ~0x7) + if (descr.capabilities & ~0x7) return fail("invalid capabilities\n"); - if (check_0(descr->reserved, sizeof(descr->reserved))) + if (check_0(descr.reserved, sizeof(descr.reserved))) return fail("non-zero reserved fields\n"); - if (descr->audioset & ~mask) + if (descr.audioset & ~mask) return fail("invalid audioset\n"); + if (descr.modulator && descr.modulator >= node->modulators) + return fail("invalid modulator\n"); return 0; } @@ -225,7 +399,7 @@ int testOutput(struct node *node) return fail("could not set output to %d\n", o); if (output != o) return fail("output set to %d, but becomes %d?!\n", o, output); - if (validOutput(&descr, o, node->audio_outputs)) + if (validOutput(node, descr, o)) return fail("invalid attributes for output %d\n", o); for (a = 0; a <= node->audio_outputs; a++) { memset(&audio, 0, sizeof(audio)); @@ -246,17 +420,17 @@ int testOutput(struct node *node) return 0; } -static int validOutputAudio(const struct v4l2_audioout *descr, unsigned o) +static int validOutputAudio(const struct v4l2_audioout &descr, unsigned o) { - if (descr->index != o) + if (descr.index != o) return fail("invalid index\n"); - if (check_ustring(descr->name, sizeof(descr->name))) + if (check_ustring(descr.name, sizeof(descr.name))) return fail("invalid name\n"); - if (descr->capability) + if (descr.capability) return fail("invalid capabilities\n"); - if (descr->mode) + if (descr.mode) return fail("invalid mode\n"); - if (check_0(descr->reserved, sizeof(descr->reserved))) + if (check_0(descr.reserved, sizeof(descr.reserved))) return fail("non-zero reserved fields\n"); return 0; } @@ -278,7 +452,7 @@ int testOutputAudio(struct node *node) break; if (ret) return fail("could not enumerate audio output %d\n", o); - if (validOutputAudio(&output, o)) + if (validOutputAudio(output, o)) return fail("invalid attributes for audio output %d\n", o); node->audio_outputs++; o++; @@ -300,7 +474,7 @@ int testOutputAudio(struct node *node) return fail("cannot get current audio output\n"); if (output.index >= node->audio_outputs) return fail("invalid current audio output %d\n", output.index); - if (validOutputAudio(&output, output.index)) + if (validOutputAudio(output, output.index)) return fail("invalid attributes for audio output %d\n", output.index); return 0; } _______________________________________________ linuxtv-commits mailing list [email protected] http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits
