Discussion:
[v4l-utils RFC 0/2] libmediatext library
Sakari Ailus
2014-10-21 10:40:13 UTC
Permalink
Hi,

This is a tiny library for parsing text-based media link, V4L2 sub-device
format (and selection) configurations as well as controls with limited
types.

This is hardly ready as such but what's there should work.
--
Regards,
Sakari
Sakari Ailus
2014-10-21 10:40:14 UTC
Permalink
Sometimes it's useful to be able to parse the entity independent of the pad.
Separate entity parsing into media_parse_entity().

Signed-off-by: Sakari Ailus <***@linux.intel.com>
---
utils/media-ctl/libmediactl.c | 28 ++++++++++++++++++++++++----
utils/media-ctl/mediactl.h | 14 ++++++++++++++
2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/utils/media-ctl/libmediactl.c b/utils/media-ctl/libmediactl.c
index ec360bd..e17d86e 100644
--- a/utils/media-ctl/libmediactl.c
+++ b/utils/media-ctl/libmediactl.c
@@ -770,10 +770,10 @@ int media_device_add_entity(struct media_device *media,
return 0;
}

-struct media_pad *media_parse_pad(struct media_device *media,
- const char *p, char **endp)
+struct media_entity *media_parse_entity(struct media_device *media,
+ const char *p, char **endp)
{
- unsigned int entity_id, pad;
+ unsigned int entity_id;
struct media_entity *entity;
char *end;

@@ -810,7 +810,27 @@ struct media_pad *media_parse_pad(struct media_device *media,
return NULL;
}
}
- for (; isspace(*end); ++end);
+ for (p = end; isspace(*p); ++p);
+
+ *endp = (char *)p;
+
+ return entity;
+}
+
+struct media_pad *media_parse_pad(struct media_device *media,
+ const char *p, char **endp)
+{
+ unsigned int pad;
+ struct media_entity *entity;
+ char *end;
+
+ if (endp == NULL)
+ endp = &end;
+
+ entity = media_parse_entity(media, p, &end);
+ if (!entity)
+ return NULL;
+ *endp = end;

if (*end != ':') {
media_dbg(media, "Expected ':'\n", *end);
diff --git a/utils/media-ctl/mediactl.h b/utils/media-ctl/mediactl.h
index 77ac182..3faee71 100644
--- a/utils/media-ctl/mediactl.h
+++ b/utils/media-ctl/mediactl.h
@@ -368,6 +368,20 @@ int media_setup_link(struct media_device *media,
int media_reset_links(struct media_device *media);

/**
+ * @brief Parse string to an entity on the media device.
+ * @param media - media device.
+ * @param p - input string
+ * @param endp - pointer to string where parsing ended
+ *
+ * Parse NULL terminated string describing an entity and return its
+ * struct media_entity instance.
+ *
+ * @return Pointer to struct media_entity on success, NULL on failure.
+ */
+struct media_entity *media_parse_entity(struct media_device *media,
+ const char *p, char **endp);
+
+/**
* @brief Parse string to a pad on the media device.
* @param media - media device.
* @param p - input string
--
2.1.0.231.g7484e3b
Sakari Ailus
2014-10-21 10:40:15 UTC
Permalink
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
Hans de Goede
2014-10-21 13:21:35 UTC
Permalink
Hi Sakari,
Post by Sakari Ailus
Hi,
This is a tiny library for parsing text-based media link, V4L2 sub-device
format (and selection) configurations as well as controls with limited
types.
Hmm, we also have:

[PATCH/RFC v2 1/4] Add a media device configuration file parser.

How do these 2 relate ?

Regards,

Hans
Sakari Ailus
2014-10-22 09:47:12 UTC
Permalink
Hi Hans,
Post by Hans de Goede
Hi Sakari,
Post by Sakari Ailus
Hi,
This is a tiny library for parsing text-based media link, V4L2 sub-device
format (and selection) configurations as well as controls with limited
types.
[PATCH/RFC v2 1/4] Add a media device configuration file parser.
How do these 2 relate ?
Jacek is working on a Samsung Exynos libv4l2 plugin, a part of which is
not specific to that plugin itself, and thus should be elsewhere
(libmediactl, for instance). I didn't know about that effort, and having
written something close to that in the past but without finishing it, I
posted mine here as well.

The common subset of functionality is limited to parsing text based link
configurations. Most of that is really implemented in libmediactl.
--
Kind regards,

Sakari Ailus
***@linux.intel.com
Hans de Goede
2014-10-23 08:19:45 UTC
Permalink
Hi,
Post by Sakari Ailus
Hi Hans,
Post by Hans de Goede
Hi Sakari,
Post by Sakari Ailus
Hi,
This is a tiny library for parsing text-based media link, V4L2 sub-device
format (and selection) configurations as well as controls with limited
types.
[PATCH/RFC v2 1/4] Add a media device configuration file parser.
How do these 2 relate ?
Jacek is working on a Samsung Exynos libv4l2 plugin, a part of which is not specific to that plugin itself, and thus should be elsewhere (libmediactl, for instance). I didn't know about that effort, and having written something close to that in the past but without finishing it, I posted mine here as well.
The common subset of functionality is limited to parsing text based link configurations. Most of that is really implemented in libmediactl.
Hmm, I guess we need to sort this out then before merging Jacek's plugin.

Jacek, have you looked into using (and if necessary extending) libmediactl
inside your plugin ?

Regards,

Hans
Jacek Anaszewski
2014-10-23 08:54:49 UTC
Permalink
Hi Hans, Sakari,
Post by Hans de Goede
Hi,
Post by Sakari Ailus
Hi Hans,
Post by Hans de Goede
Hi Sakari,
Post by Sakari Ailus
Hi,
This is a tiny library for parsing text-based media link, V4L2 sub-device
format (and selection) configurations as well as controls with limited
types.
[PATCH/RFC v2 1/4] Add a media device configuration file parser.
How do these 2 relate ?
Jacek is working on a Samsung Exynos libv4l2 plugin, a part of which is not specific to that plugin itself, and thus should be elsewhere (libmediactl, for instance). I didn't know about that effort, and having written something close to that in the past but without finishing it, I posted mine here as well.
The common subset of functionality is limited to parsing text based link configurations. Most of that is really implemented in libmediactl.
Hmm, I guess we need to sort this out then before merging Jacek's plugin.
Jacek, have you looked into using (and if necessary extending) libmediactl
inside your plugin ?
Not yet, temporarily I had to switch to different task, but I will
look into libmediactl soon to figure out how to use its API
in my plugin and what parts of my code could be added to it.

Best Regards,
Jacek Anaszewski
Hans de Goede
2014-10-23 09:31:55 UTC
Permalink
Hi,
Post by Jacek Anaszewski
Hi Hans, Sakari,
Post by Hans de Goede
Hi,
Post by Sakari Ailus
Hi Hans,
Post by Hans de Goede
Hi Sakari,
Post by Sakari Ailus
Hi,
This is a tiny library for parsing text-based media link, V4L2 sub-device
format (and selection) configurations as well as controls with limited
types.
[PATCH/RFC v2 1/4] Add a media device configuration file parser.
How do these 2 relate ?
Jacek is working on a Samsung Exynos libv4l2 plugin, a part of which is not specific to that plugin itself, and thus should be elsewhere (libmediactl, for instance). I didn't know about that effort, and having written something close to that in the past but without finishing it, I posted mine here as well.
The common subset of functionality is limited to parsing text based link configurations. Most of that is really implemented in libmediactl.
Hmm, I guess we need to sort this out then before merging Jacek's plugin.
Jacek, have you looked into using (and if necessary extending) libmediactl
inside your plugin ?
Not yet, temporarily I had to switch to different task, but I will
look into libmediactl soon to figure out how to use its API
in my plugin and what parts of my code could be added to it.
Great, I think it is best to wait with merging your plugin to this is
sorted out. Once that is sorted out I think we should be able to merge
it relatively quickly.

Maybe we should merge libmediactl into v4l-utils then ? Rather then
v4l-utils growing an external dependency on it. Sakari ?

Regards,

Hans
Sakari Ailus
2014-10-23 09:40:12 UTC
Permalink
Hi Hans,
Post by Hans de Goede
Maybe we should merge libmediactl into v4l-utils then ? Rather then
v4l-utils growing an external dependency on it. Sakari ?
libmediactl is already a part of v4l-utils, but it's under utils rather
than lib directory. Cc Laurent.
--
Kind regards,

Sakari Ailus
***@linux.intel.com
Laurent Pinchart
2014-10-23 10:01:41 UTC
Permalink
Post by Sakari Ailus
Hi Hans,
Post by Hans de Goede
Maybe we should merge libmediactl into v4l-utils then ? Rather then
v4l-utils growing an external dependency on it. Sakari ?
libmediactl is already a part of v4l-utils, but it's under utils rather
than lib directory. Cc Laurent.
I'm fine with moving the libraries to lib, but I'm still not 100% sure the ABI
can be considered stable.
--
Regards,

Laurent Pinchart
Loading...