diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 4 | ||||
| -rw-r--r-- | src/v4l2subdev.c | 92 | ||||
| -rw-r--r-- | src/v4l2subdev.h | 35 | 
3 files changed, 87 insertions, 44 deletions
@@ -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.  | 
