summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@iki.fi>2012-05-04 11:24:41 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-05-05 13:38:50 +0200
commitedad96b36f85dad7f681a7938b50b4619d11ed50 (patch)
tree49c04f475e0682f6507522cb202d2d71b9d2fc25
parent46bec667b675573cf1ce698c68112e3dbd31930e (diff)
Support selections API for crop
Support the new selections API for crop. Fall back to use the old crop API in case the selection API isn't available. Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--src/main.c4
-rw-r--r--src/v4l2subdev.c92
-rw-r--r--src/v4l2subdev.h35
3 files changed, 87 insertions, 44 deletions
diff --git a/src/main.c b/src/main.c
index 4f3271c..53964e4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -62,7 +62,9 @@ static void v4l2_subdev_print_format(struct media_entity *entity,
printf("[%s %ux%u", v4l2_subdev_pixelcode_to_string(format.code),
format.width, format.height);
- ret = v4l2_subdev_get_crop(entity, &rect, pad, which);
+ ret = v4l2_subdev_get_selection(entity, &rect, pad,
+ V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL,
+ which);
if (ret == 0)
printf(" (%u,%u)/%ux%u", rect.left, rect.top,
rect.width, rect.height);
diff --git a/src/v4l2subdev.c b/src/v4l2subdev.c
index 8c1baee..a2ab0c4 100644
--- a/src/v4l2subdev.c
+++ b/src/v4l2subdev.c
@@ -104,48 +104,83 @@ int v4l2_subdev_set_format(struct media_entity *entity,
return 0;
}
-int v4l2_subdev_get_crop(struct media_entity *entity, struct v4l2_rect *rect,
- unsigned int pad, enum v4l2_subdev_format_whence which)
+int v4l2_subdev_get_selection(struct media_entity *entity,
+ struct v4l2_rect *rect, unsigned int pad, unsigned int target,
+ enum v4l2_subdev_format_whence which)
{
- struct v4l2_subdev_crop crop;
+ union {
+ struct v4l2_subdev_selection sel;
+ struct v4l2_subdev_crop crop;
+ } u;
int ret;
ret = v4l2_subdev_open(entity);
if (ret < 0)
return ret;
- memset(&crop, 0, sizeof(crop));
- crop.pad = pad;
- crop.which = which;
+ memset(&u.sel, 0, sizeof(u.sel));
+ u.sel.pad = pad;
+ u.sel.target = target;
+ u.sel.which = which;
+
+ ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_SELECTION, &u.sel);
+ if (ret >= 0) {
+ *rect = u.sel.r;
+ return 0;
+ }
+ if (errno != ENOTTY || target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL)
+ return -errno;
+
+ memset(&u.crop, 0, sizeof(u.crop));
+ u.crop.pad = pad;
+ u.crop.which = which;
- ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_CROP, &crop);
+ ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_CROP, &u.crop);
if (ret < 0)
return -errno;
- *rect = crop.rect;
+ *rect = u.crop.rect;
return 0;
}
-int v4l2_subdev_set_crop(struct media_entity *entity, struct v4l2_rect *rect,
- unsigned int pad, enum v4l2_subdev_format_whence which)
+int v4l2_subdev_set_selection(struct media_entity *entity,
+ struct v4l2_rect *rect, unsigned int pad, unsigned int target,
+ enum v4l2_subdev_format_whence which)
{
- struct v4l2_subdev_crop crop;
+ union {
+ struct v4l2_subdev_selection sel;
+ struct v4l2_subdev_crop crop;
+ } u;
int ret;
ret = v4l2_subdev_open(entity);
if (ret < 0)
return ret;
- memset(&crop, 0, sizeof(crop));
- crop.pad = pad;
- crop.which = which;
- crop.rect = *rect;
+ memset(&u.sel, 0, sizeof(u.sel));
+ u.sel.pad = pad;
+ u.sel.target = target;
+ u.sel.which = which;
+ u.sel.r = *rect;
+
+ ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_SELECTION, &u.sel);
+ if (ret >= 0) {
+ *rect = u.sel.r;
+ return 0;
+ }
+ if (errno != ENOTTY || target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL)
+ return -errno;
+
+ memset(&u.crop, 0, sizeof(u.crop));
+ u.crop.pad = pad;
+ u.crop.which = which;
+ u.crop.rect = *rect;
- ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_CROP, &crop);
+ ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_CROP, &u.crop);
if (ret < 0)
return -errno;
- *rect = crop.rect;
+ *rect = u.crop.rect;
return 0;
}
@@ -355,30 +390,31 @@ static int set_format(struct media_pad *pad,
return 0;
}
-static int set_crop(struct media_pad *pad, struct v4l2_rect *crop)
+static int set_selection(struct media_pad *pad, unsigned int target,
+ struct v4l2_rect *rect)
{
int ret;
- if (crop->left == -1 || crop->top == -1)
+ if (rect->left == -1 || rect->top == -1)
return 0;
media_dbg(pad->entity->media,
- "Setting up crop rectangle (%u,%u)/%ux%u on pad %s/%u\n",
- crop->left, crop->top, crop->width, crop->height,
+ "Setting up selection target %u rectangle (%u,%u)/%ux%u on pad %s/%u\n",
+ target, rect->left, rect->top, rect->width, rect->height,
pad->entity->info.name, pad->index);
- ret = v4l2_subdev_set_crop(pad->entity, crop, pad->index,
- V4L2_SUBDEV_FORMAT_ACTIVE);
+ ret = v4l2_subdev_set_selection(pad->entity, rect, pad->index,
+ target, V4L2_SUBDEV_FORMAT_ACTIVE);
if (ret < 0) {
media_dbg(pad->entity->media,
- "Unable to set crop rectangle: %s (%d)\n",
+ "Unable to set selection rectangle: %s (%d)\n",
strerror(-ret), ret);
return ret;
}
media_dbg(pad->entity->media,
- "Crop rectangle set: (%u,%u)/%ux%u\n",
- crop->left, crop->top, crop->width, crop->height);
+ "Selection rectangle set: (%u,%u)/%ux%u\n",
+ rect->left, rect->top, rect->width, rect->height);
return 0;
}
@@ -430,7 +466,7 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
}
if (pad->flags & MEDIA_PAD_FL_SOURCE) {
- ret = set_crop(pad, &crop);
+ ret = set_selection(pad, V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL, &crop);
if (ret < 0)
return ret;
}
@@ -440,7 +476,7 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
return ret;
if (pad->flags & MEDIA_PAD_FL_SINK) {
- ret = set_crop(pad, &crop);
+ ret = set_selection(pad, V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL, &crop);
if (ret < 0)
return ret;
}
diff --git a/src/v4l2subdev.h b/src/v4l2subdev.h
index 1e75f94..5d55482 100644
--- a/src/v4l2subdev.h
+++ b/src/v4l2subdev.h
@@ -88,34 +88,38 @@ int v4l2_subdev_set_format(struct media_entity *entity,
enum v4l2_subdev_format_whence which);
/**
- * @brief Retrieve the crop rectangle on a pad.
+ * @brief Retrieve a selection rectangle on a pad.
* @param entity - subdev-device media entity.
- * @param rect - crop rectangle to be filled.
+ * @param r - rectangle to be filled.
* @param pad - pad number.
+ * @param target - selection target
* @param which - identifier of the format to get.
*
- * Retrieve the current crop rectangleon the @a entity @a pad and store it in
- * the @a rect structure.
+ * Retrieve the @a target selection rectangle on the @a entity @a pad
+ * and store it in the @a rect structure.
*
- * @a which is set to V4L2_SUBDEV_FORMAT_TRY to retrieve the try crop rectangle
- * stored in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to retrieve the
- * current active crop rectangle.
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to retrieve the try
+ * selection rectangle stored in the file handle, or
+ * V4L2_SUBDEV_FORMAT_ACTIVE to retrieve the current active selection
+ * rectangle.
*
* @return 0 on success, or a negative error code on failure.
*/
-int v4l2_subdev_get_crop(struct media_entity *entity, struct v4l2_rect *rect,
- unsigned int pad, enum v4l2_subdev_format_whence which);
+int v4l2_subdev_get_selection(struct media_entity *entity,
+ struct v4l2_rect *rect, unsigned int pad, unsigned int target,
+ enum v4l2_subdev_format_whence which);
/**
- * @brief Set the crop rectangle on a pad.
+ * @brief Set a selection rectangle on a pad.
* @param entity - subdev-device media entity.
* @param rect - crop rectangle.
* @param pad - pad number.
+ * @param target - selection target
* @param which - identifier of the format to set.
*
- * Set the crop rectangle on the @a entity @a pad to @a rect. The driver is
- * allowed to modify the requested rectangle, in which case @a rect is updated
- * with the modifications.
+ * Set the @a target selection rectangle on the @a entity @a pad to @a
+ * rect. The driver is allowed to modify the requested rectangle, in
+ * which case @a rect is updated with the modifications.
*
* @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the try crop rectangle
* stored in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to configure the
@@ -123,8 +127,9 @@ int v4l2_subdev_get_crop(struct media_entity *entity, struct v4l2_rect *rect,
*
* @return 0 on success, or a negative error code on failure.
*/
-int v4l2_subdev_set_crop(struct media_entity *entity, struct v4l2_rect *rect,
- unsigned int pad, enum v4l2_subdev_format_whence which);
+int v4l2_subdev_set_selection(struct media_entity *entity,
+ struct v4l2_rect *rect, unsigned int pad, unsigned int target,
+ enum v4l2_subdev_format_whence which);
/**
* @brief Retrieve the frame interval on a sub-device.