📄 v4l2_ctrl.cpp
字号:
/*
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo dot com>
Cleanup and VBI and audio in/out options:
Copyright (C) 2004 Hans Verkuil <hverkuil@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 <features.h> /* Uses _GNU_SOURCE to define getsubopt in stdlib.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <math.h>
#include <sys/klog.h>
#include <linux/videodev2.h>
#include <list>
#include <vector>
#include <map>
#include <string>
/* Short option list
Please keep in alphabetical order.
That makes it easier to see which short options are still free.
In general the lower case is used to set something and the upper
case is used to retrieve a setting. */
enum Option {
OptGetAudioInput = 'A',
OptSetAudioInput = 'a',
OptGetAudioOutput = 'B',
OptSetAudioOutput = 'b',
OptGetCtrl = 'C',
OptSetCtrl = 'c',
OptSetDevice = 'd',
OptGetDriverInfo = 'D',
OptGetFreq = 'F',
OptSetFreq = 'f',
OptHelp = 'h',
OptGetInput = 'I',
OptSetInput = 'i',
OptListCtrls = 'l',
OptListCtrlsMenus = 'L',
OptListOutputs = 'N',
OptListInputs = 'n',
OptGetOutput = 'O',
OptSetOutput = 'o',
OptListAudioOutputs = 'Q',
OptListAudioInputs = 'q',
OptGetStandard = 'S',
OptSetStandard = 's',
OptGetTuner = 'T',
OptSetTuner = 't',
OptGetVideoFormat = 'V',
OptSetVideoFormat = 'v',
OptLast = 128
};
static char options[OptLast];
static int option_all = 0;
static int option_streamoff = 0;
static int option_streamon = 0;
static int option_list_stds = 0;
static int option_version = 0;
static int option_log_status = 0;
static int option_verbose = 0;
typedef std::vector<struct v4l2_ext_control> ctrl_list;
static ctrl_list user_ctrls;
static ctrl_list mpeg_ctrls;
typedef std::map<std::string, unsigned> ctrl_strmap;
static ctrl_strmap ctrl_str2id;
typedef std::map<unsigned, std::string> ctrl_idmap;
static ctrl_idmap ctrl_id2str;
typedef std::list<std::string> ctrl_get_list;
static ctrl_get_list get_ctrls;
typedef std::map<std::string,std::string> ctrl_set_map;
static ctrl_set_map set_ctrls;
/* fmts specified */
#define FMTWidth (1L<<0)
#define FMTHeight (1L<<1)
static struct option long_options[] = {
{"list-audio-inputs", no_argument, 0, OptListAudioInputs},
{"list-audio-outputs", no_argument, 0, OptListAudioOutputs},
{"all", no_argument, &option_all, 1},
{"device", required_argument, 0, OptSetDevice},
{"get-format", no_argument, 0, OptGetVideoFormat},
{"set-format", required_argument, 0, OptSetVideoFormat},
{"help", no_argument, 0, OptHelp},
{"get-output", no_argument, 0, OptGetOutput},
{"set-output", required_argument, 0, OptSetOutput},
{"list-outputs", no_argument, 0, OptListOutputs},
{"list-inputs", no_argument, 0, OptListInputs},
{"get-input", no_argument, 0, OptGetInput},
{"set-input", required_argument, 0, OptSetInput},
{"get-audio-input", no_argument, 0, OptGetAudioInput},
{"set-audio-input", required_argument, 0, OptSetAudioInput},
{"get-audio-output", no_argument, 0, OptGetAudioOutput},
{"set-audio-output", required_argument, 0, OptSetAudioOutput},
{"get-freq", no_argument, 0, OptGetFreq},
{"set-freq", required_argument, 0, OptSetFreq},
{"streamoff", no_argument, &option_streamoff, 1},
{"streamon", no_argument, &option_streamon, 1},
{"list-standards", no_argument, &option_list_stds, 1},
{"get-standard", no_argument, 0, OptGetStandard},
{"set-standard", required_argument, 0, OptSetStandard},
{"info", no_argument, 0, OptGetDriverInfo},
{"list-ctrls", no_argument, 0, OptListCtrls},
{"list-ctrls-menus", no_argument, 0, OptListCtrlsMenus},
{"set-ctrl", required_argument, 0, OptSetCtrl},
{"get-ctrl", required_argument, 0, OptGetCtrl},
{"get-tuner", no_argument, 0, OptGetTuner},
{"set-tuner", required_argument, 0, OptSetTuner},
{"version", no_argument, &option_version, 1},
{"verbose", no_argument, &option_verbose, 1},
{"log-status", no_argument, &option_log_status, 1},
{0, 0, 0, 0}
};
void usage(void)
{
printf("Usage:\n");
printf(" --all display all information available\n");
printf(" -A, --get-audio-input\n");
printf(" query the current audio input [VIDIOC_G_AUDIO]\n");
printf(" -a, --set-audio-input=<num>\n");
printf(" set the current audio input to <num> [VIDIOC_S_AUDIO]\n");
printf(" -B, --get-audio-output\n");
printf(" query the current audio output [VIDIOC_G_AUDOUT]\n");
printf(" -b, --set-audio-output=<num>\n");
printf(" set the current audio output to <num> [VIDIOC_S_AUDOUT]\n");
printf(" -C, --get-ctrl=<ctrl>[,<ctrl>...]\n");
printf(" get the value of the controls [VIDIOC_G_EXT_CTRLS]\n");
printf(" -c, --set-ctrl=<ctrl>=<val>[,<ctrl>=<val>...]\n");
printf(" set the controls to the values specified [VIDIOC_S_EXT_CTRLS]\n");
printf(" -D, --info show driver info [VIDIOC_QUERYCAP]\n");
printf(" -d, --device=<dev> use device <dev> instead of /dev/video0\n");
printf(" if <dev> is a single digit, then /dev/video<dev> is used\n");
printf(" -F, --get-freq query the current frequency [VIDIOC_G_FREQUENCY]\n");
printf(" -f, --set-freq=<freq>\n");
printf(" set the current frequency to <freq> MHz [VIDIOC_S_FREQUENCY]\n");
printf(" -h, --help display this help message\n");
printf(" -I, --get-input query the current video input [VIDIOC_G_INPUT]\n");
printf(" -i, --set-input=<num>\n");
printf(" set the current video input to <num> [VIDIOC_S_INPUT]\n");
printf(" -l, --list-ctrls display all controls and their values [VIDIOC_QUERYCTRL]\n");
printf(" -L, --list-ctrls-menus\n");
printf(" display all controls, their values and the menus [VIDIOC_QUERYMENU]\n");
printf(" -N, --list-outputs display video outputs [VIDIOC_ENUMOUTPUT]\n");
printf(" -n, --list-inputs display video inputs [VIDIOC_ENUMINPUT]\n");
printf(" -O, --get-output query the current video output [VIDIOC_G_OUTPUT]\n");
printf(" -o, --set-output=<num>\n");
printf(" set the current video output to <num> [VIDIOC_S_OUTPUT]\n");
printf(" -Q, --list-audio-outputs\n");
printf(" display audio outputs [VIDIOC_ENUMAUDOUT]\n");
printf(" -q, --list-audio-inputs\n");
printf(" display audio inputs [VIDIOC_ENUMAUDIO]\n");
printf(" -S, --get-standard\n");
printf(" query the current video standard [VIDIOC_G_STD]\n");
printf(" -s, --set-standard=<num>\n");
printf(" set the current video standard to <num> [VIDIOC_S_STD]\n");
printf(" <num> can be a numerical v4l2_std value, or it can be one of:\n");
printf(" pal-X (X = B/G/H/N/Nc/I/D/K/M) or just 'pal' (V4L2_STD_PAL)\n");
printf(" ntsc-X (X = M/J/K) or just 'ntsc' (V4L2_STD_NTSC)\n");
printf(" secam-X (X = B/G/H/D/K/L/Lc) or just 'secam' (V4L2_STD_SECAM)\n");
printf(" --list-standards display supported video standards [VIDIOC_ENUMSTD]\n");
printf(" -T, --get-tuner query the current tuner settings [VIDIOC_G_TUNER]\n");
printf(" -t, --set-tuner=<mode>\n");
printf(" set the audio mode of the tuner [VIDIOC_S_TUNER]\n");
printf(" -V, --get-format query the current data format [VIDIOC_G_FMT]\n");
printf(" -v, --set-format=width=<x>,height=<y>\n");
printf(" set the current data format [VIDIOC_S_FMT]\n");
printf(" Possible values: 0 (mono), 1 (stereo), 2 (lang2), 3 (lang1), 4 (both)\n");
printf(" --verbose turn on verbose ioctl error reporting.\n");
printf(" --version shows the version number of this utility.\n");
printf("\n");
printf("Expert options:\n");
printf(" --streamoff turn the stream off [VIDIOC_STREAMOFF]\n");
printf(" --streamon turn the stream on [VIDIOC_STREAMOFF]\n");
printf(" --log-status log the board status in the kernel log [VIDIOC_LOG_STATUS]\n");
exit(0);
}
static std::string name2var(unsigned char *name)
{
std::string s;
while (*name) {
if (*name == ' ') s += "_";
else s += std::string(1, tolower(*name));
name++;
}
return s;
}
static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl,
struct v4l2_ext_control *ctrl, int show_menus)
{
struct v4l2_querymenu qmenu = { 0 };
std::string s = name2var(queryctrl->name);
int i;
qmenu.id = queryctrl->id;
switch (queryctrl->type) {
case V4L2_CTRL_TYPE_INTEGER:
printf("%31s (int) : min=%d max=%d step=%d default=%d value=%d",
s.c_str(),
queryctrl->minimum, queryctrl->maximum,
queryctrl->step, queryctrl->default_value,
ctrl->value);
break;
case V4L2_CTRL_TYPE_INTEGER64:
printf("%31s (int64): value=%lld", queryctrl->name, ctrl->value64);
break;
case V4L2_CTRL_TYPE_BOOLEAN:
printf("%31s (bool) : default=%d value=%d",
s.c_str(),
queryctrl->default_value, ctrl->value);
break;
case V4L2_CTRL_TYPE_MENU:
printf("%31s (menu) : min=%d max=%d default=%d value=%d",
s.c_str(),
queryctrl->minimum, queryctrl->maximum,
queryctrl->default_value, ctrl->value);
break;
case V4L2_CTRL_TYPE_BUTTON:
printf("%31s (button)\n", s.c_str());
break;
default: break;
}
if (queryctrl->flags) {
printf(" flags=");
if (queryctrl->flags & V4L2_CTRL_FLAG_GRABBED)
printf("grabbed ");
if (queryctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
printf("readonly ");
if (queryctrl->flags & V4L2_CTRL_FLAG_UPDATE)
printf("update ");
if (queryctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
printf("inactive ");
if (queryctrl->flags & V4L2_CTRL_FLAG_SLIDER)
printf("slider ");
}
printf("\n");
if (queryctrl->type == V4L2_CTRL_TYPE_MENU && show_menus) {
for (i = 0; i <= queryctrl->maximum; i++) {
qmenu.index = i;
if (ioctl(fd, VIDIOC_QUERYMENU, &qmenu))
continue;
printf("\t\t\t\t%d: %s\n", i, qmenu.name);
}
}
}
static int print_control(int fd, struct v4l2_queryctrl &qctrl, int show_menus)
{
struct v4l2_control ctrl = { 0 };
struct v4l2_ext_control ext_ctrl = { 0 };
struct v4l2_ext_controls ctrls = { 0 };
if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED)
return 1;
if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS) {
printf("\n%s\n\n", qctrl.name);
return 1;
}
ext_ctrl.id = qctrl.id;
ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(qctrl.id);
ctrls.count = 1;
ctrls.controls = &ext_ctrl;
if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_USER &&
qctrl.id < V4L2_CID_PRIVATE_BASE) {
if (ioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls)) {
printf("error %d getting ext_ctrl %s\n",
errno, qctrl.name);
return 0;
}
}
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -