linux-omap 2.6.37: sync with OE .dev
[glsdk/meta-ti-glsdk.git] / recipes-bsp / linux / linux-omap / media / 0030-v4l-v4l2_subdev-userspace-crop-API.patch
1 From 9e87e6d59dc364ec78717fb91cbe9bad7df14223 Mon Sep 17 00:00:00 2001
2 From: Antti Koskipaa <antti.koskipaa@nokia.com>
3 Date: Wed, 23 Jun 2010 11:03:42 +0300
4 Subject: [PATCH 30/43] v4l: v4l2_subdev userspace crop API
6 This patch adds the VIDIOC_SUBDEV_S_CROP and G_CROP ioctls to the
7 userland API. CROPCAP is not implemented because it's redundant.
9 Signed-off-by: Antti Koskipaa <antti.koskipaa@nokia.com>
10 Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 ---
12  Documentation/DocBook/media-entities.tmpl          |    4 +
13  Documentation/DocBook/v4l/dev-subdev.xml           |   33 +++++
14  Documentation/DocBook/v4l/v4l2.xml                 |    1 +
15  Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml |  149 ++++++++++++++++++++
16  drivers/media/video/v4l2-subdev.c                  |   26 ++++
17  include/linux/v4l2-subdev.h                        |   15 ++
18  include/media/v4l2-subdev.h                        |    4 +
19  7 files changed, 232 insertions(+), 0 deletions(-)
20  create mode 100644 Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
22 diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
23 index 4af3c2e..157d147 100644
24 --- a/Documentation/DocBook/media-entities.tmpl
25 +++ b/Documentation/DocBook/media-entities.tmpl
26 @@ -88,8 +88,10 @@
27  <!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>">
28  <!ENTITY VIDIOC-SUBDEV-ENUM-FRAME-SIZE "<link linkend='vidioc-subdev-enum-frame-size'><constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant></link>">
29  <!ENTITY VIDIOC-SUBDEV-ENUM-MBUS-CODE "<link linkend='vidioc-subdev-enum-mbus-code'><constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant></link>">
30 +<!ENTITY VIDIOC-SUBDEV-G-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_G_CROP</constant></link>">
31  <!ENTITY VIDIOC-SUBDEV-G-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_G_FMT</constant></link>">
32  <!ENTITY VIDIOC-SUBDEV-G-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant></link>">
33 +<!ENTITY VIDIOC-SUBDEV-S-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_S_CROP</constant></link>">
34  <!ENTITY VIDIOC-SUBDEV-S-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_S_FMT</constant></link>">
35  <!ENTITY VIDIOC-SUBDEV-S-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></link>">
36  <!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
37 @@ -195,6 +197,7 @@
38  <!ENTITY v4l2-subdev-frame-interval "struct&nbsp;<link linkend='v4l2-subdev-frame-interval'>v4l2_subdev_frame_interval</link>">
39  <!ENTITY v4l2-subdev-frame-interval-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-interval-enum'>v4l2_subdev_frame_interval_enum</link>">
40  <!ENTITY v4l2-subdev-frame-size-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-size-enum'>v4l2_subdev_frame_size_enum</link>">
41 +<!ENTITY v4l2-subdev-crop "struct&nbsp;<link linkend='v4l2-subdev-crop'>v4l2_subdev_crop</link>">
42  <!ENTITY v4l2-subdev-format "struct&nbsp;<link linkend='v4l2-subdev-format'>v4l2_subdev_format</link>">
43  <!ENTITY v4l2-subdev-mbus-code-enum "struct&nbsp;<link linkend='v4l2-subdev-mbus-code-enum'>v4l2_subdev_mbus_code_enum</link>">
44  <!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>">
45 @@ -333,6 +336,7 @@
46  <!ENTITY sub-subdev-enum-frame-size SYSTEM "v4l/vidioc-subdev-enum-frame-size.xml">
47  <!ENTITY sub-subdev-enum-mbus-code SYSTEM "v4l/vidioc-subdev-enum-mbus-code.xml">
48  <!ENTITY sub-subdev-formats SYSTEM "v4l/subdev-formats.xml">
49 +<!ENTITY sub-subdev-g-crop SYSTEM "v4l/vidioc-subdev-g-crop.xml">
50  <!ENTITY sub-subdev-g-fmt SYSTEM "v4l/vidioc-subdev-g-fmt.xml">
51  <!ENTITY sub-subdev-g-frame-interval SYSTEM "v4l/vidioc-subdev-g-frame-interval.xml">
52  <!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
53 diff --git a/Documentation/DocBook/v4l/dev-subdev.xml b/Documentation/DocBook/v4l/dev-subdev.xml
54 index 12fdca4..a8da916 100644
55 --- a/Documentation/DocBook/v4l/dev-subdev.xml
56 +++ b/Documentation/DocBook/v4l/dev-subdev.xml
57 @@ -269,6 +269,39 @@
58        </para>
59      </section>
60  
61 +    <section>
62 +      <title>Cropping and scaling</title>
63 +
64 +      <para>Many sub-devices support cropping frames on their input or output
65 +      pads (or possible even on both). Cropping is used to select the area of
66 +      interest in an image, typically on a video sensor or video decoder. It can
67 +      also be used as part of digital zoom implementations to select the area of
68 +      the image that will be scaled up.</para>
69 +
70 +      <para>Crop settings are defined by a crop rectangle and represented in a
71 +      &v4l2-rect; by the coordinates of the top left corner and the rectangle
72 +      size. Both the coordinates and sizes are expressed in pixels.</para>
73 +
74 +      <para>The crop rectangle is retrieved and set using the
75 +      &VIDIOC-SUBDEV-G-CROP; and &VIDIOC-SUBDEV-S-CROP; ioctls. Like for pad
76 +      formats, drivers store try and active crop rectangles. The format
77 +      negotiation mechanism applies to crop settings as well.</para>
78 +
79 +      <para>On input pads, cropping is applied relatively to the current pad
80 +      format. The pad format represents the image size as received by the
81 +      sub-device from the previous block in the pipeline, and the crop rectangle
82 +      represents the sub-image that will be transmitted further inside the
83 +      sub-device for processing. The crop rectangle be entirely containted
84 +      inside the input image size.</para>
85 +
86 +      <para>Input crop rectangle are reset to their default value when the input
87 +      image format is modified. Drivers should use the input image size as the
88 +      crop rectangle default value, but hardware requirements may prevent this.
89 +      </para>
90 +
91 +      <para>Cropping behaviour on output pads is not defined.</para>
92 +
93 +    </section>
94    </section>
95  
96    &sub-subdev-formats;
97 diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml
98 index e6225e0..5e640ca 100644
99 --- a/Documentation/DocBook/v4l/v4l2.xml
100 +++ b/Documentation/DocBook/v4l/v4l2.xml
101 @@ -481,6 +481,7 @@ and discussions on the V4L mailing list.</revremark>
102      &sub-subdev-enum-frame-interval;
103      &sub-subdev-enum-frame-size;
104      &sub-subdev-enum-mbus-code;
105 +    &sub-subdev-g-crop;
106      &sub-subdev-g-fmt;
107      &sub-subdev-g-frame-interval;
108      &sub-subscribe-event;
109 diff --git a/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml b/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
110 new file mode 100644
111 index 0000000..cef127f
112 --- /dev/null
113 +++ b/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
114 @@ -0,0 +1,149 @@
115 +<refentry id="vidioc-subdev-g-crop">
116 +  <refmeta>
117 +    <refentrytitle>ioctl VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</refentrytitle>
118 +    &manvol;
119 +  </refmeta>
121 +  <refnamediv>
122 +    <refname>VIDIOC_SUBDEV_G_CROP</refname>
123 +    <refname>VIDIOC_SUBDEV_S_CROP</refname>
124 +    <refpurpose>Get or set the crop rectangle on a subdev pad</refpurpose>
125 +  </refnamediv>
127 +  <refsynopsisdiv>
128 +    <funcsynopsis>
129 +      <funcprototype>
130 +       <funcdef>int <function>ioctl</function></funcdef>
131 +       <paramdef>int <parameter>fd</parameter></paramdef>
132 +       <paramdef>int <parameter>request</parameter></paramdef>
133 +       <paramdef>struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef>
134 +      </funcprototype>
135 +    </funcsynopsis>
136 +    <funcsynopsis>
137 +      <funcprototype>
138 +       <funcdef>int <function>ioctl</function></funcdef>
139 +       <paramdef>int <parameter>fd</parameter></paramdef>
140 +       <paramdef>int <parameter>request</parameter></paramdef>
141 +       <paramdef>const struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef>
142 +      </funcprototype>
143 +    </funcsynopsis>
144 +  </refsynopsisdiv>
146 +  <refsect1>
147 +    <title>Arguments</title>
149 +    <variablelist>
150 +      <varlistentry>
151 +       <term><parameter>fd</parameter></term>
152 +       <listitem>
153 +         <para>&fd;</para>
154 +       </listitem>
155 +      </varlistentry>
156 +      <varlistentry>
157 +       <term><parameter>request</parameter></term>
158 +       <listitem>
159 +         <para>VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</para>
160 +       </listitem>
161 +      </varlistentry>
162 +      <varlistentry>
163 +       <term><parameter>argp</parameter></term>
164 +       <listitem>
165 +         <para></para>
166 +       </listitem>
167 +      </varlistentry>
168 +    </variablelist>
169 +  </refsect1>
171 +  <refsect1>
172 +    <title>Description</title>
174 +    <para>To retrieve the current crop rectangle applications set the
175 +    <structfield>pad</structfield> field of a &v4l2-subdev-crop; to the
176 +    desired pad number as reported by the media API and the
177 +    <structfield>which</structfield> field to
178 +    <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. They then call the
179 +    <constant>VIDIOC_SUBDEV_G_CROP</constant> ioctl with a pointer to this
180 +    structure. The driver fills the members of the <structfield>rect</structfield>
181 +    field or returns &EINVAL; if the input arguments are invalid, or if cropping
182 +    is not supported on the given pad.</para>
184 +    <para>To change the current crop rectangle applications set both the
185 +    <structfield>pad</structfield> and <structfield>which</structfield> fields
186 +    and all members of the <structfield>rect</structfield> field. They then call
187 +    the <constant>VIDIOC_SUBDEV_S_CROP</constant> ioctl with a pointer to this
188 +    structure. The driver verifies the requested crop rectangle, adjusts it
189 +    based on the hardware capabilities and configures the device. Upon return
190 +    the &v4l2-subdev-crop; contains the current format as would be returned
191 +    by a <constant>VIDIOC_SUBDEV_G_CROP</constant> call.</para>
193 +    <para>Applications can query the device capabilities by setting the
194 +    <structfield>which</structfield> to
195 +    <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' crop
196 +    rectangles are not applied to the device by the driver, but are mangled
197 +    exactly as active crop rectangles and stored in the sub-device file handle.
198 +    Two applications querying the same sub-device would thus not interact with
199 +    each other.</para>
201 +    <para>Drivers must not return an error solely because the requested crop
202 +    rectangle doesn't match the device capabilities. They must instead modify
203 +    the rectangle to match what the hardware can provide. The modified format
204 +    should be as close as possible to the original request.</para>
206 +    <table pgwide="1" frame="none" id="v4l2-subdev-crop">
207 +      <title>struct <structname>v4l2_subdev_crop</structname></title>
208 +      <tgroup cols="3">
209 +        &cs-str;
210 +       <tbody valign="top">
211 +         <row>
212 +           <entry>__u32</entry>
213 +           <entry><structfield>pad</structfield></entry>
214 +           <entry>Pad number as reported by the media framework.</entry>
215 +         </row>
216 +         <row>
217 +           <entry>__u32</entry>
218 +           <entry><structfield>which</structfield></entry>
219 +           <entry>Crop rectangle to get or set, from
220 +           &v4l2-subdev-format-whence;.</entry>
221 +         </row>
222 +         <row>
223 +           <entry>&v4l2-rect;</entry>
224 +           <entry><structfield>rect</structfield></entry>
225 +           <entry>Crop rectangle boundaries, in pixels.</entry>
226 +         </row>
227 +         <row>
228 +           <entry>__u32</entry>
229 +           <entry><structfield>reserved</structfield>[8]</entry>
230 +           <entry>Reserved for future extensions. Applications and drivers must
231 +           set the array to zero.</entry>
232 +         </row>
233 +       </tbody>
234 +      </tgroup>
235 +    </table>
236 +  </refsect1>
238 +  <refsect1>
239 +    &return-value;
241 +    <variablelist>
242 +      <varlistentry>
243 +       <term><errorcode>EBUSY</errorcode></term>
244 +       <listitem>
245 +         <para>The crop rectangle can't be changed because the pad is currently
246 +         busy. This can be caused, for instance, by an active video stream on
247 +         the pad. The ioctl must not be retried without performing another
248 +         action to fix the problem first. Only returned by
249 +         <constant>VIDIOC_SUBDEV_S_CROP</constant></para>
250 +       </listitem>
251 +      </varlistentry>
252 +      <varlistentry>
253 +       <term><errorcode>EINVAL</errorcode></term>
254 +       <listitem>
255 +         <para>The &v4l2-subdev-crop; <structfield>pad</structfield>
256 +         references a non-existing pad, the <structfield>which</structfield>
257 +         field references a non-existing format, or cropping is not supported
258 +         on the given subdev pad.</para>
259 +       </listitem>
260 +      </varlistentry>
261 +    </variablelist>
262 +  </refsect1>
263 +</refentry>
264 diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
265 index 316a08a..e706c4c 100644
266 --- a/drivers/media/video/v4l2-subdev.c
267 +++ b/drivers/media/video/v4l2-subdev.c
268 @@ -213,6 +213,32 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
269                 return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format);
270         }
271  
272 +       case VIDIOC_SUBDEV_G_CROP: {
273 +               struct v4l2_subdev_crop *crop = arg;
275 +               if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
276 +                   crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
277 +                       return -EINVAL;
279 +               if (crop->pad >= sd->entity.num_pads)
280 +                       return -EINVAL;
282 +               return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
283 +       }
285 +       case VIDIOC_SUBDEV_S_CROP: {
286 +               struct v4l2_subdev_crop *crop = arg;
288 +               if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
289 +                   crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
290 +                       return -EINVAL;
292 +               if (crop->pad >= sd->entity.num_pads)
293 +                       return -EINVAL;
295 +               return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
296 +       }
298         case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
299                 struct v4l2_subdev_mbus_code_enum *code = arg;
300  
301 diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h
302 index bf9f3e9..49ec1e0 100644
303 --- a/include/linux/v4l2-subdev.h
304 +++ b/include/linux/v4l2-subdev.h
305 @@ -51,6 +51,19 @@ struct v4l2_subdev_format {
306  };
307  
308  /**
309 + * struct v4l2_subdev_crop - Pad-level crop settings
310 + * @which: format type (from enum v4l2_subdev_format_whence)
311 + * @pad: pad number, as reported by the media API
312 + * @rect: pad crop rectangle boundaries
313 + */
314 +struct v4l2_subdev_crop {
315 +       __u32 which;
316 +       __u32 pad;
317 +       struct v4l2_rect rect;
318 +       __u32 reserved[8];
319 +};
321 +/**
322   * struct v4l2_subdev_mbus_code_enum - Media bus format enumeration
323   * @pad: pad number, as reported by the media API
324   * @index: format index during enumeration
325 @@ -122,5 +135,7 @@ struct v4l2_subdev_frame_interval_enum {
326                         _IOWR('V', 74, struct v4l2_subdev_frame_size_enum)
327  #define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \
328                         _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum)
329 +#define VIDIOC_SUBDEV_G_CROP   _IOWR('V', 59, struct v4l2_subdev_crop)
330 +#define VIDIOC_SUBDEV_S_CROP   _IOWR('V', 60, struct v4l2_subdev_crop)
331  
332  #endif
333 diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
334 index 9c8bcd3..a02663e 100644
335 --- a/include/media/v4l2-subdev.h
336 +++ b/include/media/v4l2-subdev.h
337 @@ -442,6 +442,10 @@ struct v4l2_subdev_pad_ops {
338                        struct v4l2_subdev_format *format);
339         int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
340                        struct v4l2_subdev_format *format);
341 +       int (*set_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
342 +                      struct v4l2_subdev_crop *crop);
343 +       int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
344 +                      struct v4l2_subdev_crop *crop);
345  };
346  
347  struct v4l2_subdev_ops {
348 -- 
349 1.6.6.1