Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] v4l: v4l2_subdev userspace crop API

This patch adds the VIDIOC_SUBDEV_S_CROP and G_CROP ioctls to the
userland API. CROPCAP is not implemented because it's redundant.

Signed-off-by: Antti Koskipaa <akoskipa@gmail.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Antti Koskipaa and committed by
Mauro Carvalho Chehab
f6a5cb1b 35c3017a

+238
+4
Documentation/DocBook/media-entities.tmpl
··· 88 88 <!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>"> 89 89 <!ENTITY VIDIOC-SUBDEV-ENUM-FRAME-SIZE "<link linkend='vidioc-subdev-enum-frame-size'><constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant></link>"> 90 90 <!ENTITY VIDIOC-SUBDEV-ENUM-MBUS-CODE "<link linkend='vidioc-subdev-enum-mbus-code'><constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant></link>"> 91 + <!ENTITY VIDIOC-SUBDEV-G-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_G_CROP</constant></link>"> 91 92 <!ENTITY VIDIOC-SUBDEV-G-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_G_FMT</constant></link>"> 92 93 <!ENTITY VIDIOC-SUBDEV-G-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant></link>"> 94 + <!ENTITY VIDIOC-SUBDEV-S-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_S_CROP</constant></link>"> 93 95 <!ENTITY VIDIOC-SUBDEV-S-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_S_FMT</constant></link>"> 94 96 <!ENTITY VIDIOC-SUBDEV-S-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></link>"> 95 97 <!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>"> ··· 200 198 <!ENTITY v4l2-subdev-frame-interval "struct&nbsp;<link linkend='v4l2-subdev-frame-interval'>v4l2_subdev_frame_interval</link>"> 201 199 <!ENTITY v4l2-subdev-frame-interval-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-interval-enum'>v4l2_subdev_frame_interval_enum</link>"> 202 200 <!ENTITY v4l2-subdev-frame-size-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-size-enum'>v4l2_subdev_frame_size_enum</link>"> 201 + <!ENTITY v4l2-subdev-crop "struct&nbsp;<link linkend='v4l2-subdev-crop'>v4l2_subdev_crop</link>"> 203 202 <!ENTITY v4l2-subdev-format "struct&nbsp;<link linkend='v4l2-subdev-format'>v4l2_subdev_format</link>"> 204 203 <!ENTITY v4l2-subdev-mbus-code-enum "struct&nbsp;<link linkend='v4l2-subdev-mbus-code-enum'>v4l2_subdev_mbus_code_enum</link>"> 205 204 <!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>"> ··· 342 339 <!ENTITY sub-subdev-enum-frame-size SYSTEM "v4l/vidioc-subdev-enum-frame-size.xml"> 343 340 <!ENTITY sub-subdev-enum-mbus-code SYSTEM "v4l/vidioc-subdev-enum-mbus-code.xml"> 344 341 <!ENTITY sub-subdev-formats SYSTEM "v4l/subdev-formats.xml"> 342 + <!ENTITY sub-subdev-g-crop SYSTEM "v4l/vidioc-subdev-g-crop.xml"> 345 343 <!ENTITY sub-subdev-g-fmt SYSTEM "v4l/vidioc-subdev-g-fmt.xml"> 346 344 <!ENTITY sub-subdev-g-frame-interval SYSTEM "v4l/vidioc-subdev-g-frame-interval.xml"> 347 345 <!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
+33
Documentation/DocBook/v4l/dev-subdev.xml
··· 275 275 </para> 276 276 </section> 277 277 278 + <section> 279 + <title>Cropping and scaling</title> 280 + 281 + <para>Many sub-devices support cropping frames on their input or output 282 + pads (or possible even on both). Cropping is used to select the area of 283 + interest in an image, typically on a video sensor or video decoder. It can 284 + also be used as part of digital zoom implementations to select the area of 285 + the image that will be scaled up.</para> 286 + 287 + <para>Crop settings are defined by a crop rectangle and represented in a 288 + &v4l2-rect; by the coordinates of the top left corner and the rectangle 289 + size. Both the coordinates and sizes are expressed in pixels.</para> 290 + 291 + <para>The crop rectangle is retrieved and set using the 292 + &VIDIOC-SUBDEV-G-CROP; and &VIDIOC-SUBDEV-S-CROP; ioctls. Like for pad 293 + formats, drivers store try and active crop rectangles. The format 294 + negotiation mechanism applies to crop settings as well.</para> 295 + 296 + <para>On input pads, cropping is applied relatively to the current pad 297 + format. The pad format represents the image size as received by the 298 + sub-device from the previous block in the pipeline, and the crop rectangle 299 + represents the sub-image that will be transmitted further inside the 300 + sub-device for processing. The crop rectangle be entirely containted 301 + inside the input image size.</para> 302 + 303 + <para>Input crop rectangle are reset to their default value when the input 304 + image format is modified. Drivers should use the input image size as the 305 + crop rectangle default value, but hardware requirements may prevent this. 306 + </para> 307 + 308 + <para>Cropping behaviour on output pads is not defined.</para> 309 + 310 + </section> 278 311 </section> 279 312 280 313 &sub-subdev-formats;
+1
Documentation/DocBook/v4l/v4l2.xml
··· 510 510 &sub-subdev-enum-frame-interval; 511 511 &sub-subdev-enum-frame-size; 512 512 &sub-subdev-enum-mbus-code; 513 + &sub-subdev-g-crop; 513 514 &sub-subdev-g-fmt; 514 515 &sub-subdev-g-frame-interval; 515 516 &sub-subscribe-event;
+155
Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
··· 1 + <refentry id="vidioc-subdev-g-crop"> 2 + <refmeta> 3 + <refentrytitle>ioctl VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</refentrytitle> 4 + &manvol; 5 + </refmeta> 6 + 7 + <refnamediv> 8 + <refname>VIDIOC_SUBDEV_G_CROP</refname> 9 + <refname>VIDIOC_SUBDEV_S_CROP</refname> 10 + <refpurpose>Get or set the crop rectangle on a subdev pad</refpurpose> 11 + </refnamediv> 12 + 13 + <refsynopsisdiv> 14 + <funcsynopsis> 15 + <funcprototype> 16 + <funcdef>int <function>ioctl</function></funcdef> 17 + <paramdef>int <parameter>fd</parameter></paramdef> 18 + <paramdef>int <parameter>request</parameter></paramdef> 19 + <paramdef>struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef> 20 + </funcprototype> 21 + </funcsynopsis> 22 + <funcsynopsis> 23 + <funcprototype> 24 + <funcdef>int <function>ioctl</function></funcdef> 25 + <paramdef>int <parameter>fd</parameter></paramdef> 26 + <paramdef>int <parameter>request</parameter></paramdef> 27 + <paramdef>const struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef> 28 + </funcprototype> 29 + </funcsynopsis> 30 + </refsynopsisdiv> 31 + 32 + <refsect1> 33 + <title>Arguments</title> 34 + 35 + <variablelist> 36 + <varlistentry> 37 + <term><parameter>fd</parameter></term> 38 + <listitem> 39 + <para>&fd;</para> 40 + </listitem> 41 + </varlistentry> 42 + <varlistentry> 43 + <term><parameter>request</parameter></term> 44 + <listitem> 45 + <para>VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</para> 46 + </listitem> 47 + </varlistentry> 48 + <varlistentry> 49 + <term><parameter>argp</parameter></term> 50 + <listitem> 51 + <para></para> 52 + </listitem> 53 + </varlistentry> 54 + </variablelist> 55 + </refsect1> 56 + 57 + <refsect1> 58 + <title>Description</title> 59 + 60 + <note> 61 + <title>Experimental</title> 62 + <para>This is an <link linkend="experimental">experimental</link> 63 + interface and may change in the future.</para> 64 + </note> 65 + 66 + <para>To retrieve the current crop rectangle applications set the 67 + <structfield>pad</structfield> field of a &v4l2-subdev-crop; to the 68 + desired pad number as reported by the media API and the 69 + <structfield>which</structfield> field to 70 + <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. They then call the 71 + <constant>VIDIOC_SUBDEV_G_CROP</constant> ioctl with a pointer to this 72 + structure. The driver fills the members of the <structfield>rect</structfield> 73 + field or returns &EINVAL; if the input arguments are invalid, or if cropping 74 + is not supported on the given pad.</para> 75 + 76 + <para>To change the current crop rectangle applications set both the 77 + <structfield>pad</structfield> and <structfield>which</structfield> fields 78 + and all members of the <structfield>rect</structfield> field. They then call 79 + the <constant>VIDIOC_SUBDEV_S_CROP</constant> ioctl with a pointer to this 80 + structure. The driver verifies the requested crop rectangle, adjusts it 81 + based on the hardware capabilities and configures the device. Upon return 82 + the &v4l2-subdev-crop; contains the current format as would be returned 83 + by a <constant>VIDIOC_SUBDEV_G_CROP</constant> call.</para> 84 + 85 + <para>Applications can query the device capabilities by setting the 86 + <structfield>which</structfield> to 87 + <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' crop 88 + rectangles are not applied to the device by the driver, but are mangled 89 + exactly as active crop rectangles and stored in the sub-device file handle. 90 + Two applications querying the same sub-device would thus not interact with 91 + each other.</para> 92 + 93 + <para>Drivers must not return an error solely because the requested crop 94 + rectangle doesn't match the device capabilities. They must instead modify 95 + the rectangle to match what the hardware can provide. The modified format 96 + should be as close as possible to the original request.</para> 97 + 98 + <table pgwide="1" frame="none" id="v4l2-subdev-crop"> 99 + <title>struct <structname>v4l2_subdev_crop</structname></title> 100 + <tgroup cols="3"> 101 + &cs-str; 102 + <tbody valign="top"> 103 + <row> 104 + <entry>__u32</entry> 105 + <entry><structfield>pad</structfield></entry> 106 + <entry>Pad number as reported by the media framework.</entry> 107 + </row> 108 + <row> 109 + <entry>__u32</entry> 110 + <entry><structfield>which</structfield></entry> 111 + <entry>Crop rectangle to get or set, from 112 + &v4l2-subdev-format-whence;.</entry> 113 + </row> 114 + <row> 115 + <entry>&v4l2-rect;</entry> 116 + <entry><structfield>rect</structfield></entry> 117 + <entry>Crop rectangle boundaries, in pixels.</entry> 118 + </row> 119 + <row> 120 + <entry>__u32</entry> 121 + <entry><structfield>reserved</structfield>[8]</entry> 122 + <entry>Reserved for future extensions. Applications and drivers must 123 + set the array to zero.</entry> 124 + </row> 125 + </tbody> 126 + </tgroup> 127 + </table> 128 + </refsect1> 129 + 130 + <refsect1> 131 + &return-value; 132 + 133 + <variablelist> 134 + <varlistentry> 135 + <term><errorcode>EBUSY</errorcode></term> 136 + <listitem> 137 + <para>The crop rectangle can't be changed because the pad is currently 138 + busy. This can be caused, for instance, by an active video stream on 139 + the pad. The ioctl must not be retried without performing another 140 + action to fix the problem first. Only returned by 141 + <constant>VIDIOC_SUBDEV_S_CROP</constant></para> 142 + </listitem> 143 + </varlistentry> 144 + <varlistentry> 145 + <term><errorcode>EINVAL</errorcode></term> 146 + <listitem> 147 + <para>The &v4l2-subdev-crop; <structfield>pad</structfield> 148 + references a non-existing pad, the <structfield>which</structfield> 149 + field references a non-existing format, or cropping is not supported 150 + on the given subdev pad.</para> 151 + </listitem> 152 + </varlistentry> 153 + </variablelist> 154 + </refsect1> 155 + </refentry>
+26
drivers/media/video/v4l2-subdev.c
··· 213 213 return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format); 214 214 } 215 215 216 + case VIDIOC_SUBDEV_G_CROP: { 217 + struct v4l2_subdev_crop *crop = arg; 218 + 219 + if (crop->which != V4L2_SUBDEV_FORMAT_TRY && 220 + crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) 221 + return -EINVAL; 222 + 223 + if (crop->pad >= sd->entity.num_pads) 224 + return -EINVAL; 225 + 226 + return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop); 227 + } 228 + 229 + case VIDIOC_SUBDEV_S_CROP: { 230 + struct v4l2_subdev_crop *crop = arg; 231 + 232 + if (crop->which != V4L2_SUBDEV_FORMAT_TRY && 233 + crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) 234 + return -EINVAL; 235 + 236 + if (crop->pad >= sd->entity.num_pads) 237 + return -EINVAL; 238 + 239 + return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop); 240 + } 241 + 216 242 case VIDIOC_SUBDEV_ENUM_MBUS_CODE: { 217 243 struct v4l2_subdev_mbus_code_enum *code = arg; 218 244
+15
include/linux/v4l2-subdev.h
··· 51 51 }; 52 52 53 53 /** 54 + * struct v4l2_subdev_crop - Pad-level crop settings 55 + * @which: format type (from enum v4l2_subdev_format_whence) 56 + * @pad: pad number, as reported by the media API 57 + * @rect: pad crop rectangle boundaries 58 + */ 59 + struct v4l2_subdev_crop { 60 + __u32 which; 61 + __u32 pad; 62 + struct v4l2_rect rect; 63 + __u32 reserved[8]; 64 + }; 65 + 66 + /** 54 67 * struct v4l2_subdev_mbus_code_enum - Media bus format enumeration 55 68 * @pad: pad number, as reported by the media API 56 69 * @index: format index during enumeration ··· 135 122 _IOWR('V', 74, struct v4l2_subdev_frame_size_enum) 136 123 #define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \ 137 124 _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum) 125 + #define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop) 126 + #define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop) 138 127 139 128 #endif
+4
include/media/v4l2-subdev.h
··· 431 431 struct v4l2_subdev_format *format); 432 432 int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 433 433 struct v4l2_subdev_format *format); 434 + int (*set_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 435 + struct v4l2_subdev_crop *crop); 436 + int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 437 + struct v4l2_subdev_crop *crop); 434 438 }; 435 439 436 440 struct v4l2_subdev_ops {