⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 v4l2_ctrl.cpp

📁 Cleanup and VBI and audio in/out options
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                exit(1);
        }
        return opt;
}
static void parse_next_subopt(char **subs, char **value)
{
        static char *const subopts[] = {
            NULL
        };
        int opt = getsubopt(subs, subopts, value);
        if (value == NULL) {
                fprintf(stderr, "No value given to suboption <%s>\n",
                                subopts[opt]);
                usage();
                exit(1);
        }
}
int main(int argc, char **argv)
{
        char *value, *subs;
        int i;
        int fd = -1;
        /* bitfield for fmts */
        unsigned int set_fmts = 0;
        int mode = V4L2_TUNER_MODE_STEREO;      /* set audio mode */
        /* command args */
        char ch, *device = strdup("/dev/video0");       /* -d device */
        struct v4l2_format vfmt;        /* set_format/get_format */
        struct v4l2_tuner tuner;        /* set_tuner/get_tuner */
        struct v4l2_capability vcap;    /* list_cap */
        struct v4l2_input vin;          /* list_inputs */
        struct v4l2_output vout;        /* list_outputs */
        struct v4l2_audio vaudio;       /* list audio inputs */
        struct v4l2_audioout vaudout = { 0 }; /* audio outputs */
        int input;                      /* set_input/get_input */
        int output;                     /* set_output/get_output */
        v4l2_std_id std;                /* get_std/set_std */
        double freq = 0;                /* get/set frequency */
        struct v4l2_frequency vf;       /* get_freq/set_freq */
        struct v4l2_standard vs;        /* list_std */
        char short_options[26 * 2 * 2 + 1];
        int idx = 0;
        if (argc == 1) {
                usage();
                return 0;
        }
        for (i = 0; long_options[i].name; i++) {
                if (!isalpha(long_options[i].val))
                        continue;
                short_options[idx++] = long_options[i].val;
                if (long_options[i].has_arg == required_argument)
                        short_options[idx++] = ':';
        }
        while (1) {
                int option_index = 0;
                short_options[idx] = 0;
                ch = getopt_long(argc, argv, short_options,
                                 long_options, &option_index);
                if (ch == -1)
                        break;
                options[(int)ch] = 1;
                switch (ch) {
                case OptHelp:
                        usage();
                        return 0;
                case OptSetDevice:
                        device = strdup(optarg);
                        if (device[0] >= '0' && device[0] <= '9' && device[1] == 0) {
                                char dev = device[0];
                                sprintf(device, "/dev/video%c", dev);
                        }
                        break;
                case OptSetVideoFormat:
                        subs = optarg;
                        while (*subs != '\0') {
                                static char *const subopts[] = {
                                        "width",
                                        "height",
                                        NULL
                                };
                                switch (parse_subopt(&subs, subopts, &value)) {
                                case 0:
                                        vfmt.fmt.pix.width = strtol(value, 0L, 0);
                                        set_fmts |= FMTWidth;
                                        break;
                                case 1:
                                        vfmt.fmt.pix.height = strtol(value, 0L, 0);
                                        set_fmts |= FMTHeight;
                                        break;
                                }
                        }
                        break;
                case OptSetInput:
                        input = strtol(optarg, 0L, 0);
                        break;
                case OptSetOutput:
                        output = strtol(optarg, 0L, 0);
                        break;
                case OptSetAudioInput:
                        vaudio.index = strtol(optarg, 0L, 0);
                        break;
                case OptSetAudioOutput:
                        vaudout.index = strtol(optarg, 0L, 0);
                        break;
                case OptSetFreq:
                        freq = strtod(optarg, NULL);
                        break;
                case OptSetStandard:
                        if (!strncmp(optarg, "pal", 3)) {
                                if (optarg[3])
                                        std = parse_pal(optarg + 3);
                                else
                                        std = V4L2_STD_PAL;
                        }
                        else if (!strncmp(optarg, "ntsc", 4)) {
                                if (optarg[4])
                                        std = parse_ntsc(optarg + 4);
                                else
                                        std = V4L2_STD_NTSC;
                        }
                        else if (!strncmp(optarg, "secam", 5)) {
                                if (optarg[5])
                                        std = parse_secam(optarg + 5);
                                else
                                        std = V4L2_STD_SECAM;
                        }
                        else {
                                std = strtol(optarg, 0L, 0);
                        }
                        break;
                case OptGetCtrl:
                        subs = optarg;
                        while (*subs != '\0') {
                                parse_next_subopt(&subs, &value);
                                if (strchr(value, '=')) {
                                    usage();
                                    exit(1);
                                }
                                else {
                                    get_ctrls.push_back(value);
                                }
                        }
                        break;
                case OptSetCtrl:
                        subs = optarg;
                        while (*subs != '\0') {
                                parse_next_subopt(&subs, &value);
                                if (const char *equal = strchr(value, '=')) {
                                    set_ctrls[std::string(value, (equal - value))] = equal + 1;
                                }
                                else {
                                    fprintf(stderr, "control '%s' without '='\n", value);
                                    exit(1);
                                }
                        }
                        break;
                case OptSetTuner:
                        if (!strcmp(optarg, "stereo"))
                                mode = V4L2_TUNER_MODE_STEREO;
                        else if (!strcmp(optarg, "lang1"))
                                mode = V4L2_TUNER_MODE_LANG1;
                        else if (!strcmp(optarg, "lang2"))
                                mode = V4L2_TUNER_MODE_LANG2;
                        else if (!strcmp(optarg, "bilingual"))
                                mode = V4L2_TUNER_MODE_LANG1_LANG2;
                        else if (!strcmp(optarg, "mono"))
                                mode = V4L2_TUNER_MODE_MONO;
                        else {
                                fprintf(stderr, "Unknown audio mode\n");
                                usage();
                                return 1;
                        }
                        break;
                case ':':
                        fprintf(stderr, "Option `%s' requires a value\n",
                                argv[optind]);
                        usage();
                        return 1;
                case '?':
                        fprintf(stderr, "Unknown argument `%s'\n",
                                argv[optind]);
                        usage();
                        return 1;
                }
        }
        if (optind < argc) {
                printf("unknown arguments: ");
                while (optind < argc)
                        printf("%s ", argv[optind++]);
                printf("\n");
                usage();
                return 1;
        }
        if ((fd = open(device, O_RDWR)) < 0) {
                fprintf(stderr, "Failed to open %s: %s\n", device,
                        strerror(errno));
                exit(1);
        }
        free(device);
        find_controls(fd);
        for (ctrl_get_list::iterator iter = get_ctrls.begin(); iter != get_ctrls.end(); ++iter) {
            if (ctrl_str2id.find(*iter) == ctrl_str2id.end()) {
                fprintf(stderr, "unknown control '%s'\n", (*iter).c_str());
                exit(1);
            }
        }
        for (ctrl_set_map::iterator iter = set_ctrls.begin(); iter != set_ctrls.end(); ++iter) {
            if (ctrl_str2id.find(iter->first) == ctrl_str2id.end()) {
                fprintf(stderr, "unknown control '%s'\n", iter->first.c_str());
                exit(1);
            }
        }
        if (option_all) {
                options[OptGetVideoFormat] = 1;
                options[OptGetDriverInfo] = 1;
                options[OptGetInput] = 1;
                options[OptGetOutput] = 1;
                options[OptGetAudioInput] = 1;
                options[OptGetAudioOutput] = 1;
                options[OptGetStandard] = 1;
                options[OptGetFreq] = 1;
                options[OptGetTuner] = 1;
        }
        /* Setting Opts */
        if (options[OptSetVideoFormat]) {
                struct v4l2_format in_vfmt;
                printf("ioctl: VIDIOC_S_FMT\n");
                in_vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                if (ioctl(fd, VIDIOC_G_FMT, &in_vfmt) < 0)
                        fprintf(stderr, "ioctl: VIDIOC_G_FMT failed\n");
                else {
                        printf("\tBefore:\n");
                        if (printfmt(in_vfmt) != 0)
                                fprintf(stderr, "error printing result\n");
                        if (set_fmts & FMTWidth)
                                in_vfmt.fmt.pix.width = vfmt.fmt.pix.width;
                        if (set_fmts & FMTHeight)
                                in_vfmt.fmt.pix.height = vfmt.fmt.pix.height;
                        if (ioctl(fd, VIDIOC_S_FMT, &in_vfmt) < 0)
                                fprintf(stderr, "ioctl: VIDIOC_S_FMT failed\n");
                        vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                        if (ioctl(fd, VIDIOC_G_FMT, &vfmt) < 0)
                                fprintf(stderr, "ioctl: VIDIOC_G_FMT failed\n");
                        else {
                                printf("\n\tAfter:\n");
                                if (printfmt(vfmt) != 0)
                                        fprintf(stderr,
                                                "error printing result\n");
                        }
                }
        }
        if (option_streamoff) {
                int dummy = 0;
                doioctl(fd, VIDIOC_STREAMOFF, &dummy, "VIDIOC_STREAMOFF");
        }
        if (options[OptSetFreq]) {
                double fac = 16;
                if (doioctl(fd, VIDIOC_G_TUNER, &tuner, "VIDIOC_G_TUNER") == 0) {
                        fac = (tuner.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16;
                }
                vf.tuner = 0;
                vf.type = tuner.type;
                vf.frequency = __u32(freq * fac);
                if (doioctl(fd, VIDIOC_S_FREQUENCY, &vf,
                        "VIDIOC_S_FREQUENCY") == 0)
                        printf("Frequency set to %d (%f MHz)\n", vf.frequency,
                                        vf.frequency / fac);
        }
        if (options[OptSetStandard]) {
                if (std < 16) {
                        vs.index = std;
                        if (ioctl(fd, VIDIOC_ENUMSTD, &vs) >= 0) {
                                std = vs.id;
                        }
                }
                if (doioctl(fd, VIDIOC_S_STD, &std, "VIDIOC_S_STD") == 0)
                        printf("Standard set to %08llx\n", (unsigned long long)std);
        }
        if (options[OptSetCtrl] && !set_ctrls.empty()) {
                struct v4l2_ext_controls ctrls = { 0 };
                for (ctrl_set_map::iterator iter = set_ctrls.begin();
                                iter != set_ctrls.end(); ++iter) {
                        struct v4l2_ext_control ctrl = { 0 };
                        ctrl.id = ctrl_str2id[iter->first];
                        ctrl.value = atol(iter->second.c_str());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -