Commit ae184cda8d0eebfea6cf217abc3f94a7cfffe24d

Authored by Sakari Ailus
Committed by Mauro Carvalho Chehab
1 parent c520331a52

[media] v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs

Add support for VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION
IOCTLs. They replace functionality provided by VIDIOC_SUBDEV_S_CROP and
VIDIOC_SUBDEV_G_CROP IOCTLs and also add new functionality (composing).

VIDIOC_SUBDEV_G_CROP and VIDIOC_SUBDEV_S_CROP continue to be supported.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 3 changed files with 90 additions and 14 deletions Side-by-side Diff

drivers/media/video/v4l2-subdev.c
... ... @@ -35,14 +35,9 @@
35 35 static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
36 36 {
37 37 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
38   - /* Allocate try format and crop in the same memory block */
39   - fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop))
40   - * sd->entity.num_pads, GFP_KERNEL);
41   - if (fh->try_fmt == NULL)
  38 + fh->pad = kzalloc(sizeof(*fh->pad) * sd->entity.num_pads, GFP_KERNEL);
  39 + if (fh->pad == NULL)
42 40 return -ENOMEM;
43   -
44   - fh->try_crop = (struct v4l2_rect *)
45   - (fh->try_fmt + sd->entity.num_pads);
46 41 #endif
47 42 return 0;
48 43 }
... ... @@ -50,9 +45,8 @@
50 45 static void subdev_fh_free(struct v4l2_subdev_fh *fh)
51 46 {
52 47 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
53   - kfree(fh->try_fmt);
54   - fh->try_fmt = NULL;
55   - fh->try_crop = NULL;
  48 + kfree(fh->pad);
  49 + fh->pad = NULL;
56 50 #endif
57 51 }
58 52  
... ... @@ -292,6 +286,34 @@
292 286  
293 287 return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh,
294 288 fie);
  289 + }
  290 +
  291 + case VIDIOC_SUBDEV_G_SELECTION: {
  292 + struct v4l2_subdev_selection *sel = arg;
  293 +
  294 + if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
  295 + sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
  296 + return -EINVAL;
  297 +
  298 + if (sel->pad >= sd->entity.num_pads)
  299 + return -EINVAL;
  300 +
  301 + return v4l2_subdev_call(
  302 + sd, pad, get_selection, subdev_fh, sel);
  303 + }
  304 +
  305 + case VIDIOC_SUBDEV_S_SELECTION: {
  306 + struct v4l2_subdev_selection *sel = arg;
  307 +
  308 + if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
  309 + sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
  310 + return -EINVAL;
  311 +
  312 + if (sel->pad >= sd->entity.num_pads)
  313 + return -EINVAL;
  314 +
  315 + return v4l2_subdev_call(
  316 + sd, pad, set_selection, subdev_fh, sel);
295 317 }
296 318 #endif
297 319 default:
include/linux/v4l2-subdev.h
... ... @@ -123,6 +123,43 @@
123 123 __u32 reserved[9];
124 124 };
125 125  
  126 +#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE (1 << 0)
  127 +#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE (1 << 1)
  128 +#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG (1 << 2)
  129 +
  130 +/* active cropping area */
  131 +#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL 0x0000
  132 +/* cropping bounds */
  133 +#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS 0x0002
  134 +/* current composing area */
  135 +#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL 0x0100
  136 +/* composing bounds */
  137 +#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS 0x0102
  138 +
  139 +
  140 +/**
  141 + * struct v4l2_subdev_selection - selection info
  142 + *
  143 + * @which: either V4L2_SUBDEV_FORMAT_ACTIVE or V4L2_SUBDEV_FORMAT_TRY
  144 + * @pad: pad number, as reported by the media API
  145 + * @target: selection target, used to choose one of possible rectangles
  146 + * @flags: constraint flags
  147 + * @r: coordinates of the selection window
  148 + * @reserved: for future use, set to zero for now
  149 + *
  150 + * Hardware may use multiple helper windows to process a video stream.
  151 + * The structure is used to exchange this selection areas between
  152 + * an application and a driver.
  153 + */
  154 +struct v4l2_subdev_selection {
  155 + __u32 which;
  156 + __u32 pad;
  157 + __u32 target;
  158 + __u32 flags;
  159 + struct v4l2_rect r;
  160 + __u32 reserved[8];
  161 +};
  162 +
126 163 #define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
127 164 #define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format)
128 165 #define VIDIOC_SUBDEV_G_FRAME_INTERVAL \
... ... @@ -137,6 +174,10 @@
137 174 _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum)
138 175 #define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop)
139 176 #define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop)
  177 +#define VIDIOC_SUBDEV_G_SELECTION \
  178 + _IOWR('V', 61, struct v4l2_subdev_selection)
  179 +#define VIDIOC_SUBDEV_S_SELECTION \
  180 + _IOWR('V', 62, struct v4l2_subdev_selection)
140 181  
141 182 #endif
include/media/v4l2-subdev.h
... ... @@ -466,6 +466,10 @@
466 466 struct v4l2_subdev_crop *crop);
467 467 int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
468 468 struct v4l2_subdev_crop *crop);
  469 + int (*get_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
  470 + struct v4l2_subdev_selection *sel);
  471 + int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
  472 + struct v4l2_subdev_selection *sel);
469 473 };
470 474  
471 475 struct v4l2_subdev_ops {
... ... @@ -549,8 +553,11 @@
549 553 struct v4l2_subdev_fh {
550 554 struct v4l2_fh vfh;
551 555 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
552   - struct v4l2_mbus_framefmt *try_fmt;
553   - struct v4l2_rect *try_crop;
  556 + struct {
  557 + struct v4l2_mbus_framefmt try_fmt;
  558 + struct v4l2_rect try_crop;
  559 + struct v4l2_rect try_compose;
  560 + } *pad;
554 561 #endif
555 562 };
556 563  
557 564  
... ... @@ -561,13 +568,19 @@
561 568 static inline struct v4l2_mbus_framefmt *
562 569 v4l2_subdev_get_try_format(struct v4l2_subdev_fh *fh, unsigned int pad)
563 570 {
564   - return &fh->try_fmt[pad];
  571 + return &fh->pad[pad].try_fmt;
565 572 }
566 573  
567 574 static inline struct v4l2_rect *
568 575 v4l2_subdev_get_try_crop(struct v4l2_subdev_fh *fh, unsigned int pad)
569 576 {
570   - return &fh->try_crop[pad];
  577 + return &fh->pad[pad].try_crop;
  578 +}
  579 +
  580 +static inline struct v4l2_rect *
  581 +v4l2_subdev_get_try_compose(struct v4l2_subdev_fh *fh, unsigned int pad)
  582 +{
  583 + return &fh->pad[pad].try_compose;
571 584 }
572 585 #endif
573 586