summaryrefslogtreecommitdiff
path: root/src/v4l2subdev.c
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@iki.fi>2012-05-23 01:30:57 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-05-25 12:19:29 +0200
commit79fc1080b905dc3d61a93c31f68acaf3b4985c57 (patch)
tree5736f16181fb81ed10604485c54fd6ac644ba1ec /src/v4l2subdev.c
parent4aa40df9cfaf6f94b9207023d8ac9250847d2150 (diff)
New, more flexible syntax for format
More flexible and extensible syntax for format which allows better usage of the selection API. Continue supporting the old syntax but remove the documentation for it. It was not supported in an official release and its use is thus deprecated. Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/v4l2subdev.c')
-rw-r--r--src/v4l2subdev.c90
1 files changed, 64 insertions, 26 deletions
diff --git a/src/v4l2subdev.c b/src/v4l2subdev.c
index a2ab0c4..bc33610 100644
--- a/src/v4l2subdev.c
+++ b/src/v4l2subdev.c
@@ -25,6 +25,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -232,14 +233,19 @@ static int v4l2_subdev_parse_format(struct v4l2_mbus_framefmt *format,
unsigned int width, height;
char *end;
+ /*
+ * Compatibility with the old syntax: consider space as valid
+ * separator between the media bus pixel code and the size.
+ */
for (; isspace(*p); ++p);
- for (end = (char *)p; !isspace(*end) && *end != '\0'; ++end);
+ for (end = (char *)p;
+ *end != '/' && *end != ' ' && *end != '\0'; ++end);
code = v4l2_subdev_string_to_pixelcode(p, end - p);
if (code == (enum v4l2_mbus_pixelcode)-1)
return -EINVAL;
- for (p = end; isspace(*p); ++p);
+ p = end + 1;
width = strtoul(p, &end, 10);
if (*end != 'x')
return -EINVAL;
@@ -256,32 +262,32 @@ static int v4l2_subdev_parse_format(struct v4l2_mbus_framefmt *format,
return 0;
}
-static int v4l2_subdev_parse_crop(
- struct v4l2_rect *crop, const char *p, char **endp)
+static int v4l2_subdev_parse_rectangle(
+ struct v4l2_rect *r, const char *p, char **endp)
{
char *end;
if (*p++ != '(')
return -EINVAL;
- crop->left = strtoul(p, &end, 10);
+ r->left = strtoul(p, &end, 10);
if (*end != ',')
return -EINVAL;
p = end + 1;
- crop->top = strtoul(p, &end, 10);
+ r->top = strtoul(p, &end, 10);
if (*end++ != ')')
return -EINVAL;
if (*end != '/')
return -EINVAL;
p = end + 1;
- crop->width = strtoul(p, &end, 10);
+ r->width = strtoul(p, &end, 10);
if (*end != 'x')
return -EINVAL;
p = end + 1;
- crop->height = strtoul(p, &end, 10);
+ r->height = strtoul(p, &end, 10);
*endp = end;
return 0;
@@ -307,12 +313,29 @@ static int v4l2_subdev_parse_frame_interval(struct v4l2_fract *interval,
return 0;
}
+/*
+ * The debate over whether this function should be named icanhasstr() instead
+ * has been strong and heated. If you feel like this would be an important
+ * change, patches are welcome (or not).
+ */
+static bool strhazit(const char *str, const char **p)
+{
+ int len = strlen(str);
+
+ if (strncmp(str, *p, len))
+ return false;
+
+ for (*p += len; isspace(**p); ++*p);
+ return true;
+}
+
static struct media_pad *v4l2_subdev_parse_pad_format(
struct media_device *media, struct v4l2_mbus_framefmt *format,
struct v4l2_rect *crop, struct v4l2_fract *interval, const char *p,
char **endp)
{
struct media_pad *pad;
+ bool first;
char *end;
int ret;
@@ -326,30 +349,45 @@ static struct media_pad *v4l2_subdev_parse_pad_format(
if (*p++ != '[')
return NULL;
- for (; isspace(*p); ++p);
+ for (first = true; ; first = false) {
+ for (; isspace(*p); p++);
- if (isalnum(*p)) {
- ret = v4l2_subdev_parse_format(format, p, &end);
- if (ret < 0)
- return NULL;
+ /*
+ * Backward compatibility: if the first property starts with an
+ * uppercase later, process it as a format description.
+ */
+ if (strhazit("fmt:", &p) || (first && isupper(*p))) {
+ ret = v4l2_subdev_parse_format(format, p, &end);
+ if (ret < 0)
+ return NULL;
- for (p = end; isspace(*p); p++);
- }
+ p = end;
+ continue;
+ }
- if (*p == '(') {
- ret = v4l2_subdev_parse_crop(crop, p, &end);
- if (ret < 0)
- return NULL;
+ /*
+ * Backward compatibility: crop rectangles can be specified
+ * implicitly without the 'crop:' property name.
+ */
+ if (strhazit("crop:", &p) || *p == '(') {
+ ret = v4l2_subdev_parse_rectangle(crop, p, &end);
+ if (ret < 0)
+ return NULL;
+
+ p = end;
+ continue;
+ }
- for (p = end; isspace(*p); p++);
- }
+ if (*p == '@') {
+ ret = v4l2_subdev_parse_frame_interval(interval, ++p, &end);
+ if (ret < 0)
+ return NULL;
- if (*p == '@') {
- ret = v4l2_subdev_parse_frame_interval(interval, ++p, &end);
- if (ret < 0)
- return NULL;
+ p = end;
+ continue;
+ }
- for (p = end; isspace(*p); p++);
+ break;
}
if (*p != ']')