Commit ae184cda8d0eebfea6cf217abc3f94a7cfffe24d
Committed by
Mauro Carvalho Chehab
1 parent
c520331a52
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
[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 |