From dcc1f2aebb01437a2b43125ca986c7ffc5e702e7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 20 May 2014 16:54:27 +0200 Subject: Add field support for the media bus format Signed-off-by: Laurent Pinchart --- src/main.c | 3 +++ src/v4l2subdev.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/v4l2subdev.h | 25 ++++++++++++++++++++++- 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 6f980b4..57618d6 100644 --- a/src/main.c +++ b/src/main.c @@ -63,6 +63,9 @@ static void v4l2_subdev_print_format(struct media_entity *entity, v4l2_subdev_pixelcode_to_string(format.code), format.width, format.height); + if (format.field) + printf(" field:%s", v4l2_subdev_field_to_string(format.field)); + ret = v4l2_subdev_get_selection(entity, &rect, pad, V4L2_SEL_TGT_CROP_BOUNDS, which); diff --git a/src/v4l2subdev.c b/src/v4l2subdev.c index 6c7f9ec..f55de9d 100644 --- a/src/v4l2subdev.c +++ b/src/v4l2subdev.c @@ -401,6 +401,24 @@ static struct media_pad *v4l2_subdev_parse_pad_format( continue; } + if (strhazit("field:", &p)) { + enum v4l2_field field; + + for (end = (char *)p; isalpha(*end) || *end == '-'; ++end); + + field = v4l2_subdev_string_to_field(p, end - p); + if (field == (enum v4l2_field)-1) { + media_dbg(media, "Invalid field value '%*s'\n", end - p, p); + *endp = (char *)p; + return NULL; + } + + format->field = field; + + p = end; + continue; + } + /* * Backward compatibility: crop rectangles can be specified * implicitly without the 'crop:' property name. @@ -683,3 +701,47 @@ enum v4l2_mbus_pixelcode v4l2_subdev_string_to_pixelcode(const char *string, return mbus_formats[i].code; } + +static struct { + const char *name; + enum v4l2_field field; +} fields[] = { + { "any", V4L2_FIELD_ANY }, + { "none", V4L2_FIELD_NONE }, + { "top", V4L2_FIELD_TOP }, + { "bottom", V4L2_FIELD_BOTTOM }, + { "interlaced", V4L2_FIELD_INTERLACED }, + { "seq-tb", V4L2_FIELD_SEQ_TB }, + { "seq-bt", V4L2_FIELD_SEQ_BT }, + { "alternate", V4L2_FIELD_ALTERNATE }, + { "interlaced-tb", V4L2_FIELD_INTERLACED_TB }, + { "interlaced-bt", V4L2_FIELD_INTERLACED_BT }, +}; + +const char *v4l2_subdev_field_to_string(enum v4l2_field field) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(fields); ++i) { + if (fields[i].field == field) + return fields[i].name; + } + + return "unknown"; +} + +enum v4l2_field v4l2_subdev_string_to_field(const char *string, + unsigned int length) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(fields); ++i) { + if (strncmp(fields[i].name, string, length) == 0) + break; + } + + if (i == ARRAY_SIZE(fields)) + return (enum v4l2_field)-1; + + return fields[i].field; +} diff --git a/src/v4l2subdev.h b/src/v4l2subdev.h index 5d55482..4589739 100644 --- a/src/v4l2subdev.h +++ b/src/v4l2subdev.h @@ -194,7 +194,7 @@ const char *v4l2_subdev_pixelcode_to_string(enum v4l2_mbus_pixelcode code); /** * @brief Parse string to media bus pixel code. * @param string - input string - * @param lenght - length of the string + * @param length - length of the string * * Parse human readable string @a string to an media bus pixel code. * @@ -202,4 +202,27 @@ const char *v4l2_subdev_pixelcode_to_string(enum v4l2_mbus_pixelcode code); */ enum v4l2_mbus_pixelcode v4l2_subdev_string_to_pixelcode(const char *string, unsigned int length); + +/** + * @brief Convert a field order to string. + * @param field - field order + * + * Convert field order @a field to a human-readable string. + * + * @return A pointer to a string on success, NULL on failure. + */ +const char *v4l2_subdev_field_to_string(enum v4l2_field field); + +/** + * @brief Parse string to field order. + * @param string - input string + * @param length - length of the string + * + * Parse human readable string @a string to field order. + * + * @return field order on success, -1 on failure. + */ +enum v4l2_field v4l2_subdev_string_to_field(const char *string, + unsigned int length); + #endif -- cgit v1.2.3