summaryrefslogtreecommitdiff
path: root/v4l2-apps/util
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-08-02 12:07:00 +0200
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-08-02 12:07:00 +0200
commit83670264a7c9fca11f962b5b7f344e0909433439 (patch)
treee7985c4cbd6c79e16e6bc573a1c6c7bae812d8a2 /v4l2-apps/util
parentd129cf91ea1355d0b5ff68d3720bc89fca4c7570 (diff)
downloadmediapointer-dvb-s2-83670264a7c9fca11f962b5b7f344e0909433439.tar.gz
mediapointer-dvb-s2-83670264a7c9fca11f962b5b7f344e0909433439.tar.bz2
v4l2-ctl: add support for string controls
From: Hans Verkuil <hverkuil@xs4all.nl> Add support for string controls to v4l2-ctl. Also refactor the code to generalize the handling of control classes. Priority: normal Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'v4l2-apps/util')
-rw-r--r--v4l2-apps/util/v4l2-ctl.cpp227
1 files changed, 136 insertions, 91 deletions
diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp
index 70b85d0d0..955b95be0 100644
--- a/v4l2-apps/util/v4l2-ctl.cpp
+++ b/v4l2-apps/util/v4l2-ctl.cpp
@@ -148,20 +148,17 @@ static int verbose;
static unsigned capabilities;
-typedef std::vector<struct v4l2_ext_control> ctrl_list;
-static ctrl_list user_ctrls;
-static ctrl_list mpeg_ctrls;
-static ctrl_list camera_ctrls;
+typedef std::map<unsigned, std::vector<struct v4l2_ext_control> > class2ctrls_map;
-typedef std::map<std::string, unsigned> ctrl_strmap;
-static ctrl_strmap ctrl_str2id;
+typedef std::map<std::string, struct v4l2_queryctrl> ctrl_qmap;
+static ctrl_qmap ctrl_str2q;
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;
+typedef std::map<std::string, std::string> ctrl_set_map;
static ctrl_set_map set_ctrls;
typedef std::vector<std::string> dev_vec;
@@ -583,6 +580,43 @@ static std::string name2var(unsigned char *name)
return s;
}
+static std::string safename(const unsigned char *name)
+{
+ std::string s;
+
+ while (*name) {
+ if (*name == '\n') {
+ s += "\\n";
+ }
+ else if (*name == '\r') {
+ s += "\\r";
+ }
+ else if (*name == '\f') {
+ s += "\\f";
+ }
+ else if (*name == '\\') {
+ s += "\\\\";
+ }
+ else if ((*name & 0x7f) < 0x20) {
+ char buf[3];
+
+ sprintf(buf, "%02x", *name);
+ s += "\\x";
+ s += buf;
+ }
+ else {
+ s += *name;
+ }
+ name++;
+ }
+ return s;
+}
+
+static std::string safename(const char *name)
+{
+ return safename((const unsigned char *)name);
+}
+
static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl,
struct v4l2_ext_control *ctrl, int show_menus)
{
@@ -602,6 +636,12 @@ static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl,
case V4L2_CTRL_TYPE_INTEGER64:
printf("%31s (int64): value=%lld", s.c_str(), ctrl->value64);
break;
+ case V4L2_CTRL_TYPE_STRING:
+ printf("%31s (str) : min=%d max=%d step=%d value='%s'",
+ s.c_str(),
+ queryctrl->minimum, queryctrl->maximum,
+ queryctrl->step, safename(ctrl->string).c_str());
+ break;
case V4L2_CTRL_TYPE_BOOLEAN:
printf("%31s (bool) : default=%d value=%d",
s.c_str(),
@@ -659,6 +699,11 @@ static int print_control(int fd, struct v4l2_queryctrl &qctrl, int show_menus)
ctrls.controls = &ext_ctrl;
if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_USER &&
qctrl.id < V4L2_CID_PRIVATE_BASE) {
+ if (qctrl.type == V4L2_CTRL_TYPE_STRING) {
+ ext_ctrl.size = qctrl.maximum + 1;
+ ext_ctrl.string = (char *)malloc(ext_ctrl.size);
+ ext_ctrl.string[0] = 0;
+ }
if (ioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls)) {
printf("error %d getting ext_ctrl %s\n",
errno, qctrl.name);
@@ -675,6 +720,8 @@ static int print_control(int fd, struct v4l2_queryctrl &qctrl, int show_menus)
ext_ctrl.value = ctrl.value;
}
print_qctrl(fd, &qctrl, &ext_ctrl, show_menus);
+ if (qctrl.type == V4L2_CTRL_TYPE_STRING)
+ free(ext_ctrl.string);
return 1;
}
@@ -708,7 +755,7 @@ static void find_controls(int fd)
while (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) {
if (qctrl.type != V4L2_CTRL_TYPE_CTRL_CLASS &&
!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
- ctrl_str2id[name2var(qctrl.name)] = qctrl.id;
+ ctrl_str2q[name2var(qctrl.name)] = qctrl;
ctrl_id2str[qctrl.id] = name2var(qctrl.name);
}
qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
@@ -719,14 +766,14 @@ static void find_controls(int fd)
qctrl.id = id;
if (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0 &&
!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
- ctrl_str2id[name2var(qctrl.name)] = qctrl.id;
+ ctrl_str2q[name2var(qctrl.name)] = qctrl;
ctrl_id2str[qctrl.id] = name2var(qctrl.name);
}
}
for (qctrl.id = V4L2_CID_PRIVATE_BASE;
ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) {
if (!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
- ctrl_str2id[name2var(qctrl.name)] = qctrl.id;
+ ctrl_str2q[name2var(qctrl.name)] = qctrl;
ctrl_id2str[qctrl.id] = name2var(qctrl.name);
}
}
@@ -1926,13 +1973,13 @@ int main(int argc, char **argv)
capabilities = vcap.capabilities;
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()) {
+ if (ctrl_str2q.find(*iter) == ctrl_str2q.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()) {
+ if (ctrl_str2q.find(iter->first) == ctrl_str2q.end()) {
fprintf(stderr, "unknown control '%s'\n", iter->first.c_str());
exit(1);
}
@@ -2261,60 +2308,61 @@ set_vid_fmt_error:
if (options[OptSetCtrl] && !set_ctrls.empty()) {
struct v4l2_ext_controls ctrls = { 0 };
+ class2ctrls_map class2ctrls;
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 = strtol(iter->second.c_str(), NULL, 0);
- if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_MPEG)
- mpeg_ctrls.push_back(ctrl);
- else if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_CAMERA)
- camera_ctrls.push_back(ctrl);
- else
- user_ctrls.push_back(ctrl);
- }
- for (unsigned i = 0; i < user_ctrls.size(); i++) {
- struct v4l2_control ctrl;
-
- ctrl.id = user_ctrls[i].id;
- ctrl.value = user_ctrls[i].value;
- if (doioctl(fd, VIDIOC_S_CTRL, &ctrl, "VIDIOC_S_CTRL")) {
- fprintf(stderr, "%s: %s\n",
- ctrl_id2str[ctrl.id].c_str(),
- strerror(errno));
- }
- }
- if (mpeg_ctrls.size()) {
- ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
- ctrls.count = mpeg_ctrls.size();
- ctrls.controls = &mpeg_ctrls[0];
- if (doioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls, "VIDIOC_S_EXT_CTRLS")) {
- if (ctrls.error_idx >= ctrls.count) {
- fprintf(stderr, "Error setting MPEG controls: %s\n",
- strerror(errno));
+ ctrl.id = ctrl_str2q[iter->first].id;
+ if (ctrl_str2q[iter->first].type == V4L2_CTRL_TYPE_STRING) {
+ unsigned len = iter->second.length();
+ unsigned maxlen = ctrl_str2q[iter->first].maximum;
+
+ ctrl.size = maxlen + 1;
+ ctrl.string = (char *)malloc(ctrl.size);
+ if (len > maxlen) {
+ memcpy(ctrl.string, iter->second.c_str(), maxlen);
+ ctrl.string[maxlen] = 0;
}
else {
- fprintf(stderr, "%s: %s\n",
- ctrl_id2str[mpeg_ctrls[ctrls.error_idx].id].c_str(),
- strerror(errno));
+ strcpy(ctrl.string, iter->second.c_str());
}
+ } else {
+ ctrl.value = strtol(iter->second.c_str(), NULL, 0);
}
+ class2ctrls[V4L2_CTRL_ID2CLASS(ctrl.id)].push_back(ctrl);
}
- if (camera_ctrls.size()) {
- ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
- ctrls.count = camera_ctrls.size();
- ctrls.controls = &camera_ctrls[0];
- if (doioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls, "VIDIOC_S_EXT_CTRLS")) {
- if (ctrls.error_idx >= ctrls.count) {
- fprintf(stderr, "Error setting CAMERA controls: %s\n",
- strerror(errno));
+ for (class2ctrls_map::iterator iter = class2ctrls.begin();
+ iter != class2ctrls.end(); ++iter) {
+ if (iter->first == V4L2_CTRL_CLASS_USER) {
+ for (unsigned i = 0; i < iter->second.size(); i++) {
+ struct v4l2_control ctrl;
+
+ ctrl.id = iter->second[i].id;
+ ctrl.value = iter->second[i].value;
+ if (doioctl(fd, VIDIOC_S_CTRL, &ctrl, "VIDIOC_S_CTRL")) {
+ fprintf(stderr, "%s: %s\n",
+ ctrl_id2str[ctrl.id].c_str(),
+ strerror(errno));
+ }
}
- else {
- fprintf(stderr, "%s: %s\n",
- ctrl_id2str[camera_ctrls[ctrls.error_idx].id].c_str(),
- strerror(errno));
+ continue;
+ }
+ if (iter->second.size()) {
+ ctrls.ctrl_class = iter->first;
+ ctrls.count = iter->second.size();
+ ctrls.controls = &iter->second[0];
+ if (doioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls, "VIDIOC_S_EXT_CTRLS")) {
+ if (ctrls.error_idx >= ctrls.count) {
+ fprintf(stderr, "Error setting MPEG controls: %s\n",
+ strerror(errno));
+ }
+ else {
+ fprintf(stderr, "%s: %s\n",
+ ctrl_id2str[iter->second[ctrls.error_idx].id].c_str(),
+ strerror(errno));
+ }
}
}
}
@@ -2585,49 +2633,46 @@ set_vid_fmt_error:
if (options[OptGetCtrl] && !get_ctrls.empty()) {
struct v4l2_ext_controls ctrls = { 0 };
+ class2ctrls_map class2ctrls;
- mpeg_ctrls.clear();
- camera_ctrls.clear();
- user_ctrls.clear();
for (ctrl_get_list::iterator iter = get_ctrls.begin();
iter != get_ctrls.end(); ++iter) {
struct v4l2_ext_control ctrl = { 0 };
- ctrl.id = ctrl_str2id[*iter];
- if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_MPEG)
- mpeg_ctrls.push_back(ctrl);
- else if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_CAMERA)
- camera_ctrls.push_back(ctrl);
- else
- user_ctrls.push_back(ctrl);
- }
- for (unsigned i = 0; i < user_ctrls.size(); i++) {
- struct v4l2_control ctrl;
-
- ctrl.id = user_ctrls[i].id;
- doioctl(fd, VIDIOC_G_CTRL, &ctrl, "VIDIOC_G_CTRL");
- printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value);
- }
- if (mpeg_ctrls.size()) {
- ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
- ctrls.count = mpeg_ctrls.size();
- ctrls.controls = &mpeg_ctrls[0];
- doioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls, "VIDIOC_G_EXT_CTRLS");
- for (unsigned i = 0; i < mpeg_ctrls.size(); i++) {
- struct v4l2_ext_control ctrl = mpeg_ctrls[i];
-
- printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value);
+ ctrl.id = ctrl_str2q[*iter].id;
+ if (ctrl_str2q[*iter].type == V4L2_CTRL_TYPE_STRING) {
+ ctrl.size = ctrl_str2q[*iter].maximum + 1;
+ ctrl.string = (char *)malloc(ctrl.size);
+ ctrl.string[0] = 0;
}
+ class2ctrls[V4L2_CTRL_ID2CLASS(ctrl.id)].push_back(ctrl);
}
- if (camera_ctrls.size()) {
- ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
- ctrls.count = camera_ctrls.size();
- ctrls.controls = &camera_ctrls[0];
- doioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls, "VIDIOC_G_EXT_CTRLS");
- for (unsigned i = 0; i < camera_ctrls.size(); i++) {
- struct v4l2_ext_control ctrl = camera_ctrls[i];
-
- printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value);
+ for (class2ctrls_map::iterator iter = class2ctrls.begin();
+ iter != class2ctrls.end(); ++iter) {
+ if (iter->first == V4L2_CTRL_CLASS_USER) {
+ for (unsigned i = 0; i < iter->second.size(); i++) {
+ struct v4l2_control ctrl;
+
+ ctrl.id = iter->second[i].id;
+ doioctl(fd, VIDIOC_G_CTRL, &ctrl, "VIDIOC_G_CTRL");
+ printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value);
+ }
+ continue;
+ }
+ if (iter->second.size()) {
+ ctrls.ctrl_class = iter->first;
+ ctrls.count = iter->second.size();
+ ctrls.controls = &iter->second[0];
+ doioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls, "VIDIOC_G_EXT_CTRLS");
+ for (unsigned i = 0; i < iter->second.size(); i++) {
+ struct v4l2_ext_control ctrl = iter->second[i];
+
+ if (ctrl_str2q[ctrl_id2str[ctrl.id]].type == V4L2_CTRL_TYPE_STRING)
+ printf("%s: '%s'\n", ctrl_id2str[ctrl.id].c_str(),
+ safename(ctrl.string).c_str());
+ else
+ printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value);
+ }
}
}
}