libmediatext is a helper library for converting configurations (Media
controller links, V4L2 controls and V4L2 sub-device media bus formats a=
nd
selections) from text-based form into IOCTLs.
libmediatext depends on libv4l2subdev and libmediactl.
Signed-off-by: Sakari Ailus <***@linux.intel.com>
Signed-off-by: Teemu Tuominen <***@intel.com>
---
libmediatext.pc.in | 10 ++
utils/media-ctl/Makefile.am | 10 +-
utils/media-ctl/libmediatext.pc.in | 10 ++
utils/media-ctl/mediatext-test.c | 65 ++++++++++++
utils/media-ctl/mediatext.c | 210 +++++++++++++++++++++++++++++=
++++++++
utils/media-ctl/mediatext.h | 29 +++++
6 files changed, 332 insertions(+), 2 deletions(-)
create mode 100644 libmediatext.pc.in
create mode 100644 utils/media-ctl/libmediatext.pc.in
create mode 100644 utils/media-ctl/mediatext-test.c
create mode 100644 utils/media-ctl/mediatext.c
create mode 100644 utils/media-ctl/mediatext.h
diff --git a/libmediatext.pc.in b/libmediatext.pc.in
new file mode 100644
index 0000000..6aa6353
--- /dev/null
+++ b/libmediatext.pc.in
@@ -0,0 +1,10 @@
+prefix=***@prefix@
+exec_prefix=***@exec_prefix@
+libdir=***@libdir@
+includedir=***@includedir@
+
+Name: libmediatext
+Description: Media controller and V4L2 text-based configuration librar=
y
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -lmediatext
diff --git a/utils/media-ctl/Makefile.am b/utils/media-ctl/Makefile.am
index a3931fb..3e883e0 100644
--- a/utils/media-ctl/Makefile.am
+++ b/utils/media-ctl/Makefile.am
@@ -1,4 +1,4 @@
-noinst_LTLIBRARIES =3D libmediactl.la libv4l2subdev.la
+noinst_LTLIBRARIES =3D libmediactl.la libv4l2subdev.la libmediatext.la
=20
libmediactl_la_SOURCES =3D libmediactl.c mediactl-priv.h
libmediactl_la_CFLAGS =3D -static $(LIBUDEV_CFLAGS)
@@ -9,9 +9,15 @@ libv4l2subdev_la_LIBADD =3D libmediactl.la
libv4l2subdev_la_CFLAGS =3D -static
libv4l2subdev_la_LDFLAGS =3D -static
=20
+libmediatext_la_SOURCES =3D mediatext.c
+libmediatext_la_CFLAGS =3D -static $(LIBUDEV_CFLAGS)
+libmediatext_la_LDFLAGS =3D -static $(LIBUDEV_LIBS)
+
mediactl_includedir=3D$(includedir)/mediactl
noinst_HEADERS =3D mediactl.h v4l2subdev.h
=20
-bin_PROGRAMS =3D media-ctl
+bin_PROGRAMS =3D media-ctl mediatext-test
media_ctl_SOURCES =3D media-ctl.c options.c options.h tools.h
media_ctl_LDADD =3D libmediactl.la libv4l2subdev.la
+mediatext_test_SOURCES =3D mediatext-test.c
+mediatext_test_LDADD =3D libmediatext.la libmediactl.la libv4l2subdev.=
la
diff --git a/utils/media-ctl/libmediatext.pc.in b/utils/media-ctl/libme=
diatext.pc.in
new file mode 100644
index 0000000..6aa6353
--- /dev/null
+++ b/utils/media-ctl/libmediatext.pc.in
@@ -0,0 +1,10 @@
+prefix=***@prefix@
+exec_prefix=***@exec_prefix@
+libdir=***@libdir@
+includedir=***@includedir@
+
+Name: libmediatext
+Description: Media controller and V4L2 text-based configuration librar=
y
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -lmediatext
diff --git a/utils/media-ctl/mediatext-test.c b/utils/media-ctl/mediate=
xt-test.c
new file mode 100644
index 0000000..296b8c0
--- /dev/null
+++ b/utils/media-ctl/mediatext-test.c
@@ -0,0 +1,65 @@
+/*
+ * libmediatext test program
+ *
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Contact: Sakari Ailus <***@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modif=
y
+ * it under the terms of the GNU Lesser General Public License as publ=
ished
+ * by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public Li=
cense
+ * along with this program. If not, see <http://www.gnu.org/licenses/>=
=2E
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mediactl.h"
+#include "mediatext.h"
+
+int main(int argc, char *argv[])
+{
+ struct media_device *device;
+ int rval;
+
+ if (argc !=3D 3) {
+ fprintf(stderr, "usage: %s <media device> <string>\n\n", argv[0]);
+ fprintf(stderr, "\tstring :=3D [ v4l2-ctrl |=A0v4l2-mbus | link-rese=
t | link-conf]\n\n");
+ fprintf(stderr, "\tv4l2-ctrl :=3D \"entity\" ctrl_type ctrl_id ctrl_=
value\n");
+ fprintf(stderr, "\tctrl_type :=3D [ int | int64 | bitmask ]\n");
+ fprintf(stderr, "\tctrl_value :=3D [ %%d | %%PRId64 | bitmask_value =
]\n");
+ fprintf(stderr, "\tbitmask_value :=3D b<binary_number>\n\n");
+ fprintf(stderr, "\tv4l2-mbus :=3D \n");
+ fprintf(stderr, "\tlink-conf :=3D \"entity\":pad -> \"entity\":pad[l=
ink-flags]\n");
+ return EXIT_FAILURE;
+ }
+
+ device =3D media_device_new(argv[1]);
+ if (!device)
+ return EXIT_FAILURE;
+
+ media_debug_set_handler(device, (void (*)(void *, ...))fprintf, stdou=
t);
+
+ rval =3D media_device_enumerate(device);
+ if (rval)
+ return EXIT_FAILURE;
+
+ rval =3D mediatext_parse(device, argv[2]);
+ if (rval) {
+ fprintf(stderr, "bad string %s (%s)\n", argv[2], strerror(-rval));
+ return EXIT_FAILURE;
+ }
+
+ media_device_unref(device);
+
+ return EXIT_SUCCESS;
+}
diff --git a/utils/media-ctl/mediatext.c b/utils/media-ctl/mediatext.c
new file mode 100644
index 0000000..ce0ee42
--- /dev/null
+++ b/utils/media-ctl/mediatext.c
@@ -0,0 +1,210 @@
+/*
+ * Media controller text-based configuration library
+ *
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Contact: Sakari Ailus <***@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modif=
y
+ * it under the terms of the GNU Lesser General Public License as publ=
ished
+ * by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public Li=
cense
+ * along with this program. If not, see <http://www.gnu.org/licenses/>=
=2E
+ */
+
+#include <sys/ioctl.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <linux/types.h>
+
+#include "mediactl.h"
+#include "mediactl-priv.h"
+#include "tools.h"
+#include "v4l2subdev.h"
+
+struct parser {
+ char *prefix;
+ int (*parse)(struct media_device *media, const struct parser *p,
+ char *string);
+ struct parser *next;
+ bool no_args;
+};
+
+static int parse(struct media_device *media, const struct parser *p, c=
har *string)
+{
+ for (; p->prefix; p++) {
+ size_t len =3D strlen(p->prefix);
+
+ if (strncmp(p->prefix, string, len))
+ continue;
+
+ string +=3D len;
+
+ for (; isspace(*string); string++);
+
+ if (p->no_args)
+ return p->parse(media, p->next, NULL);
+
+ if (strlen(string) =3D=3D 0)
+ return -ENOEXEC;
+
+ return p->parse(media, p->next, string);
+ }
+
+ return -ENOENT;
+}
+
+struct ctrl_type {
+ uint32_t type;
+ char *str;
+} ctrltypes[] =3D {
+ { V4L2_CTRL_TYPE_INTEGER, "int" },
+ { V4L2_CTRL_TYPE_MENU, "menu" },
+ { V4L2_CTRL_TYPE_INTEGER_MENU, "intmenu" },
+ { V4L2_CTRL_TYPE_BITMASK, "bitmask" },
+ { V4L2_CTRL_TYPE_INTEGER64, "int64" },
+};
+
+/* adapted from yavta.c */
+static int parse_v4l2_ctrl(struct media_device *media, const struct pa=
rser *p,
+ char *string)
+{
+ struct v4l2_ext_control ctrl =3D { 0 };
+ struct v4l2_ext_controls ctrls =3D { .count =3D 1,
+ .controls =3D &ctrl };
+ int64_t val;
+ int rval;
+ struct media_entity *entity;
+ struct ctrl_type *ctype;
+ unsigned int i;
+
+ entity =3D media_parse_entity(media, string, &string);
+ if (!entity)
+ return -ENOENT;
+
+ for (i =3D 0; i < ARRAY_SIZE(ctrltypes); i++)
+ if (!strncmp(string, ctrltypes[i].str,
+ strlen(ctrltypes[i].str)))
+ break;
+
+ if (i =3D=3D ARRAY_SIZE(ctrltypes))
+ return -ENOENT;
+
+ ctype =3D &ctrltypes[i];
+
+ string +=3D strlen(ctrltypes[i].str);
+ for (; isspace(*string); string++);
+ rval =3D sscanf(string, "0x%" PRIx32, &ctrl.id);
+ if (rval <=3D 0)
+ return -EINVAL;
+
+ for (; !isspace(*string) && *string; string++);
+ for (; isspace(*string); string++);
+
+ ctrls.ctrl_class =3D V4L2_CTRL_ID2CLASS(ctrl.id);
+
+ switch (ctype->type) {
+ case V4L2_CTRL_TYPE_BITMASK:
+ if (*string++ !=3D 'b')
+ return -EINVAL;
+ while (*string =3D=3D '1' || *string =3D=3D '0') {
+ val <<=3D 1;
+ if (*string =3D=3D '1')
+ val++;
+ string++;
+ }
+ break;
+ default:
+ rval =3D sscanf(string, "%" PRId64, &val);
+ break;
+ }
+ if (rval <=3D 0)
+ return -EINVAL;
+
+ media_dbg(media, "Setting control 0x%8.8x (type %s), value %" PRId64 =
"\n",
+ ctrl.id, ctype->str, val);
+
+ if (ctype->type =3D=3D V4L2_CTRL_TYPE_INTEGER64)
+ ctrl.value64 =3D val;
+ else
+ ctrl.value =3D val;
+
+ rval =3D v4l2_subdev_open(entity);
+ if (rval < 0)
+ return rval;
+
+ rval =3D ioctl(entity->fd, VIDIOC_S_EXT_CTRLS, &ctrls);
+ if (ctype->type !=3D V4L2_CTRL_TYPE_INTEGER64) {
+ if (rval !=3D -1) {
+ ctrl.value64 =3D ctrl.value;
+ } else if (ctype->type !=3D V4L2_CTRL_TYPE_STRING &&
+ (errno =3D=3D EINVAL || errno =3D=3D ENOTTY)) {
+ struct v4l2_control old =3D { .id =3D ctrl.id,
+ .value =3D val };
+
+ rval =3D ioctl(entity->fd, VIDIOC_S_CTRL, &old);
+ if (rval !=3D -1) {
+ ctrl.value64 =3D old.value;
+ }
+ }
+ }
+ if (rval =3D=3D -1) {
+ media_dbg(media,
+ "Failed setting control 0x8.8x: %s (%d) to value %"
+ PRId64 "\n", ctrl.id, strerror(errno), errno, val);;
+ return -errno;
+ }
+
+ if (val !=3D ctrl.value64)
+ media_dbg(media, "Asking for %" PRId64 ", got %" PRId64 "\n",
+ val, ctrl.value64);
+
+ return 0;
+}
+
+static int parse_v4l2_mbus(struct media_device *media, const struct pa=
rser *p,
+ char *string)
+{
+ media_dbg(media, "Media bus format setup: %s\n", string);
+ return v4l2_subdev_parse_setup_formats(media, string);
+}
+
+static int parse_link_reset(struct media_device *media, const struct p=
arser *p,
+ char *string)
+{
+ media_dbg(media, "Resetting links\n");
+ return media_reset_links(media);
+}
+
+static int parse_link_conf(struct media_device *media, const struct pa=
rser *p,
+ char *string)
+{
+ media_dbg(media, "Configuring links: %s\n", string);
+ return media_parse_setup_links(media, string);
+}
+
+static const struct parser parsers[] =3D {
+ { "v4l2-ctrl", parse_v4l2_ctrl },
+ { "v4l2-mbus", parse_v4l2_mbus },
+ { "link-reset", parse_link_reset, NULL, true },
+ { "link-conf", parse_link_conf },
+ { 0 }
+};
+
+int mediatext_parse(struct media_device *media, char *string)
+{
+ return parse(media, parsers, string);
+}
diff --git a/utils/media-ctl/mediatext.h b/utils/media-ctl/mediatext.h
new file mode 100644
index 0000000..f2f80fe
--- /dev/null
+++ b/utils/media-ctl/mediatext.h
@@ -0,0 +1,29 @@
+/*
+ * Media controller text-based configuration library
+ *
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Contact: Sakari Ailus <***@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modif=
y
+ * it under the terms of the GNU Lesser General Public License as publ=
ished
+ * by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public Li=
cense
+ * along with this program. If not, see <http://www.gnu.org/licenses/>=
=2E
+ */
+
+#ifndef __MEDIATEXT_H__
+#define __MEDIATEXT_H__
+
+struct media_device;
+
+int mediatext_parse(struct media_device *device, char *string);
+
+#endif /* __MEDIATEXT_H__ */
--=20
2.1.0.231.g7484e3b