summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorTodor Tomov <ttomov@mm-sol.com>2010-06-30 10:55:43 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2010-07-01 10:34:32 +0200
commita04e11ca5bbf2a44539ee14e3077358a21262ba2 (patch)
tree8ea3e86da132a77ab8ccee3b909e727620db29ec /main.c
parentc13258a74fd7345828fce8fab117247e3f61e6e5 (diff)
V4L2 subdev frame interval support
Extend the V4L2 media bus format syntax to support an optional frame interval value. If specified, the frame interval is set on the subdev. Signed-off-by: Todor Tomov <ttomov@mm-sol.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'main.c')
-rw-r--r--main.c62
1 files changed, 59 insertions, 3 deletions
diff --git a/main.c b/main.c
index 9b8951a..96b7ca1 100644
--- a/main.c
+++ b/main.c
@@ -230,9 +230,28 @@ static int parse_crop(struct v4l2_rect *crop, const char *p, char **endp)
return 0;
}
+static int parse_frame_interval(struct v4l2_fract *interval, const char *p, char **endp)
+{
+ char *end;
+
+ for (; isspace(*p); ++p);
+
+ interval->numerator = strtoul(p, &end, 10);
+
+ for (p = end; isspace(*p); ++p);
+ if (*p++ != '/')
+ return -EINVAL;
+
+ for (; isspace(*p); ++p);
+ interval->denominator = strtoul(p, &end, 10);
+
+ *endp = end;
+ return 0;
+}
+
static struct media_entity_pad *parse_pad_format(struct media_device *media,
struct v4l2_mbus_framefmt *format, struct v4l2_rect *crop,
- const char *p, char **endp)
+ struct v4l2_fract *interval, const char *p, char **endp)
{
struct media_entity_pad *pad;
char *end;
@@ -253,7 +272,7 @@ static struct media_entity_pad *parse_pad_format(struct media_device *media,
return NULL;
for (p = end; isspace(*p); p++);
- if (*p != ']') {
+ if (isdigit(*p)) {
ret = parse_crop(crop, p, &end);
if (ret < 0)
return NULL;
@@ -261,6 +280,14 @@ static struct media_entity_pad *parse_pad_format(struct media_device *media,
for (p = end; isspace(*p); p++);
}
+ if (*p == '@') {
+ ret = parse_frame_interval(interval, ++p, &end);
+ if (ret < 0)
+ return NULL;
+
+ for (p = end; isspace(*p); p++);
+ }
+
if (*p != ']')
return NULL;
@@ -310,16 +337,37 @@ static int set_crop(struct media_entity_pad *pad, struct v4l2_rect *crop)
return 0;
}
+static int set_frame_interval(struct media_entity *entity, struct v4l2_fract *interval)
+{
+ int ret;
+
+ printf("Setting up frame interval %u/%u on entity %s\n",
+ interval->numerator, interval->denominator, entity->info.name);
+
+ ret = v4l2_subdev_set_frame_interval(entity, interval);
+ if (ret < 0) {
+ printf("Unable to set frame interval: %s (%d)", strerror(-ret), ret);
+ return ret;
+ }
+
+ printf("Frame interval set: %u/%u\n",
+ interval->numerator, interval->denominator);
+
+ return 0;
+}
+
+
static int setup_format(struct media_device *media, const char *p, char **endp)
{
struct v4l2_mbus_framefmt format;
struct media_entity_pad *pad;
struct v4l2_rect crop = { -1, -1, -1, -1 };
+ struct v4l2_fract interval = { 0, 0 };
unsigned int i;
char *end;
int ret;
- pad = parse_pad_format(media, &format, &crop, p, &end);
+ pad = parse_pad_format(media, &format, &crop, &interval, p, &end);
if (pad == NULL) {
printf("Unable to parse format\n");
return -EINVAL;
@@ -339,6 +387,14 @@ static int setup_format(struct media_device *media, const char *p, char **endp)
}
}
+ if (interval.numerator != 0) {
+ ret = set_frame_interval(pad->entity, &interval);
+ if (ret < 0) {
+ printf("Unable to set frame interval\n");
+ return ret;
+ }
+ }
+
/* If the pad is an output pad, automatically set the same format on
* the remote subdev input pads, if any.
*/