diff options
author | Todor Tomov <ttomov@mm-sol.com> | 2010-06-30 10:55:43 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2010-07-01 10:34:32 +0200 |
commit | a04e11ca5bbf2a44539ee14e3077358a21262ba2 (patch) | |
tree | 8ea3e86da132a77ab8ccee3b909e727620db29ec /main.c | |
parent | c13258a74fd7345828fce8fab117247e3f61e6e5 (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.c | 62 |
1 files changed, 59 insertions, 3 deletions
@@ -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. */ |