aboutsummaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap/media/0030-v4l-v4l2_subdev-userspace-crop-API.patch
blob: d1a3aae8732218619bdaaf1c9185a0ef0282acc4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
From 9e87e6d59dc364ec78717fb91cbe9bad7df14223 Mon Sep 17 00:00:00 2001
From: Antti Koskipaa <antti.koskipaa@nokia.com>
Date: Wed, 23 Jun 2010 11:03:42 +0300
Subject: [PATCH 30/43] 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 <antti.koskipaa@nokia.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 Documentation/DocBook/media-entities.tmpl          |    4 +
 Documentation/DocBook/v4l/dev-subdev.xml           |   33 +++++
 Documentation/DocBook/v4l/v4l2.xml                 |    1 +
 Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml |  149 ++++++++++++++++++++
 drivers/media/video/v4l2-subdev.c                  |   26 ++++
 include/linux/v4l2-subdev.h                        |   15 ++
 include/media/v4l2-subdev.h                        |    4 +
 7 files changed, 232 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml

diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
index 4af3c2e..157d147 100644
--- a/Documentation/DocBook/media-entities.tmpl
+++ b/Documentation/DocBook/media-entities.tmpl
@@ -88,8 +88,10 @@
 <!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>">
 <!ENTITY VIDIOC-SUBDEV-ENUM-FRAME-SIZE "<link linkend='vidioc-subdev-enum-frame-size'><constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant></link>">
 <!ENTITY VIDIOC-SUBDEV-ENUM-MBUS-CODE "<link linkend='vidioc-subdev-enum-mbus-code'><constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant></link>">
+<!ENTITY VIDIOC-SUBDEV-G-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_G_CROP</constant></link>">
 <!ENTITY VIDIOC-SUBDEV-G-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_G_FMT</constant></link>">
 <!ENTITY VIDIOC-SUBDEV-G-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant></link>">
+<!ENTITY VIDIOC-SUBDEV-S-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_S_CROP</constant></link>">
 <!ENTITY VIDIOC-SUBDEV-S-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_S_FMT</constant></link>">
 <!ENTITY VIDIOC-SUBDEV-S-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></link>">
 <!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
@@ -195,6 +197,7 @@
 <!ENTITY v4l2-subdev-frame-interval "struct&nbsp;<link linkend='v4l2-subdev-frame-interval'>v4l2_subdev_frame_interval</link>">
 <!ENTITY v4l2-subdev-frame-interval-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-interval-enum'>v4l2_subdev_frame_interval_enum</link>">
 <!ENTITY v4l2-subdev-frame-size-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-size-enum'>v4l2_subdev_frame_size_enum</link>">
+<!ENTITY v4l2-subdev-crop "struct&nbsp;<link linkend='v4l2-subdev-crop'>v4l2_subdev_crop</link>">
 <!ENTITY v4l2-subdev-format "struct&nbsp;<link linkend='v4l2-subdev-format'>v4l2_subdev_format</link>">
 <!ENTITY v4l2-subdev-mbus-code-enum "struct&nbsp;<link linkend='v4l2-subdev-mbus-code-enum'>v4l2_subdev_mbus_code_enum</link>">
 <!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>">
@@ -333,6 +336,7 @@
 <!ENTITY sub-subdev-enum-frame-size SYSTEM "v4l/vidioc-subdev-enum-frame-size.xml">
 <!ENTITY sub-subdev-enum-mbus-code SYSTEM "v4l/vidioc-subdev-enum-mbus-code.xml">
 <!ENTITY sub-subdev-formats SYSTEM "v4l/subdev-formats.xml">
+<!ENTITY sub-subdev-g-crop SYSTEM "v4l/vidioc-subdev-g-crop.xml">
 <!ENTITY sub-subdev-g-fmt SYSTEM "v4l/vidioc-subdev-g-fmt.xml">
 <!ENTITY sub-subdev-g-frame-interval SYSTEM "v4l/vidioc-subdev-g-frame-interval.xml">
 <!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
diff --git a/Documentation/DocBook/v4l/dev-subdev.xml b/Documentation/DocBook/v4l/dev-subdev.xml
index 12fdca4..a8da916 100644
--- a/Documentation/DocBook/v4l/dev-subdev.xml
+++ b/Documentation/DocBook/v4l/dev-subdev.xml
@@ -269,6 +269,39 @@
       </para>
     </section>
 
+    <section>
+      <title>Cropping and scaling</title>
+
+      <para>Many sub-devices support cropping frames on their input or output
+      pads (or possible even on both). Cropping is used to select the area of
+      interest in an image, typically on a video sensor or video decoder. It can
+      also be used as part of digital zoom implementations to select the area of
+      the image that will be scaled up.</para>
+
+      <para>Crop settings are defined by a crop rectangle and represented in a
+      &v4l2-rect; by the coordinates of the top left corner and the rectangle
+      size. Both the coordinates and sizes are expressed in pixels.</para>
+
+      <para>The crop rectangle is retrieved and set using the
+      &VIDIOC-SUBDEV-G-CROP; and &VIDIOC-SUBDEV-S-CROP; ioctls. Like for pad
+      formats, drivers store try and active crop rectangles. The format
+      negotiation mechanism applies to crop settings as well.</para>
+
+      <para>On input pads, cropping is applied relatively to the current pad
+      format. The pad format represents the image size as received by the
+      sub-device from the previous block in the pipeline, and the crop rectangle
+      represents the sub-image that will be transmitted further inside the
+      sub-device for processing. The crop rectangle be entirely containted
+      inside the input image size.</para>
+
+      <para>Input crop rectangle are reset to their default value when the input
+      image format is modified. Drivers should use the input image size as the
+      crop rectangle default value, but hardware requirements may prevent this.
+      </para>
+
+      <para>Cropping behaviour on output pads is not defined.</para>
+
+    </section>
   </section>
 
   &sub-subdev-formats;
diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml
index e6225e0..5e640ca 100644
--- a/Documentation/DocBook/v4l/v4l2.xml
+++ b/Documentation/DocBook/v4l/v4l2.xml
@@ -481,6 +481,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-subdev-enum-frame-interval;
     &sub-subdev-enum-frame-size;
     &sub-subdev-enum-mbus-code;
+    &sub-subdev-g-crop;
     &sub-subdev-g-fmt;
     &sub-subdev-g-frame-interval;
     &sub-subscribe-event;
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml b/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
new file mode 100644
index 0000000..cef127f
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
@@ -0,0 +1,149 @@
+<refentry id="vidioc-subdev-g-crop">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_SUBDEV_G_CROP</refname>
+    <refname>VIDIOC_SUBDEV_S_CROP</refname>
+    <refpurpose>Get or set the crop rectangle on a subdev pad</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To retrieve the current crop rectangle applications set the
+    <structfield>pad</structfield> field of a &v4l2-subdev-crop; to the
+    desired pad number as reported by the media API and the
+    <structfield>which</structfield> field to
+    <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. They then call the
+    <constant>VIDIOC_SUBDEV_G_CROP</constant> ioctl with a pointer to this
+    structure. The driver fills the members of the <structfield>rect</structfield>
+    field or returns &EINVAL; if the input arguments are invalid, or if cropping
+    is not supported on the given pad.</para>
+
+    <para>To change the current crop rectangle applications set both the
+    <structfield>pad</structfield> and <structfield>which</structfield> fields
+    and all members of the <structfield>rect</structfield> field. They then call
+    the <constant>VIDIOC_SUBDEV_S_CROP</constant> ioctl with a pointer to this
+    structure. The driver verifies the requested crop rectangle, adjusts it
+    based on the hardware capabilities and configures the device. Upon return
+    the &v4l2-subdev-crop; contains the current format as would be returned
+    by a <constant>VIDIOC_SUBDEV_G_CROP</constant> call.</para>
+
+    <para>Applications can query the device capabilities by setting the
+    <structfield>which</structfield> to
+    <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' crop
+    rectangles are not applied to the device by the driver, but are mangled
+    exactly as active crop rectangles and stored in the sub-device file handle.
+    Two applications querying the same sub-device would thus not interact with
+    each other.</para>
+
+    <para>Drivers must not return an error solely because the requested crop
+    rectangle doesn't match the device capabilities. They must instead modify
+    the rectangle to match what the hardware can provide. The modified format
+    should be as close as possible to the original request.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-crop">
+      <title>struct <structname>v4l2_subdev_crop</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media framework.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>which</structfield></entry>
+	    <entry>Crop rectangle to get or set, from
+	    &v4l2-subdev-format-whence;.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-rect;</entry>
+	    <entry><structfield>rect</structfield></entry>
+	    <entry>Crop rectangle boundaries, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>Reserved for future extensions. Applications and drivers must
+	    set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The crop rectangle can't be changed because the pad is currently
+	  busy. This can be caused, for instance, by an active video stream on
+	  the pad. The ioctl must not be retried without performing another
+	  action to fix the problem first. Only returned by
+	  <constant>VIDIOC_SUBDEV_S_CROP</constant></para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-subdev-crop; <structfield>pad</structfield>
+	  references a non-existing pad, the <structfield>which</structfield>
+	  field references a non-existing format, or cropping is not supported
+	  on the given subdev pad.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index 316a08a..e706c4c 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -213,6 +213,32 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format);
 	}
 
+	case VIDIOC_SUBDEV_G_CROP: {
+		struct v4l2_subdev_crop *crop = arg;
+
+		if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
+		    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+			return -EINVAL;
+
+		if (crop->pad >= sd->entity.num_pads)
+			return -EINVAL;
+
+		return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
+	}
+
+	case VIDIOC_SUBDEV_S_CROP: {
+		struct v4l2_subdev_crop *crop = arg;
+
+		if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
+		    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+			return -EINVAL;
+
+		if (crop->pad >= sd->entity.num_pads)
+			return -EINVAL;
+
+		return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
+	}
+
 	case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
 		struct v4l2_subdev_mbus_code_enum *code = arg;
 
diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h
index bf9f3e9..49ec1e0 100644
--- a/include/linux/v4l2-subdev.h
+++ b/include/linux/v4l2-subdev.h
@@ -51,6 +51,19 @@ struct v4l2_subdev_format {
 };
 
 /**
+ * struct v4l2_subdev_crop - Pad-level crop settings
+ * @which: format type (from enum v4l2_subdev_format_whence)
+ * @pad: pad number, as reported by the media API
+ * @rect: pad crop rectangle boundaries
+ */
+struct v4l2_subdev_crop {
+	__u32 which;
+	__u32 pad;
+	struct v4l2_rect rect;
+	__u32 reserved[8];
+};
+
+/**
  * struct v4l2_subdev_mbus_code_enum - Media bus format enumeration
  * @pad: pad number, as reported by the media API
  * @index: format index during enumeration
@@ -122,5 +135,7 @@ struct v4l2_subdev_frame_interval_enum {
 			_IOWR('V', 74, struct v4l2_subdev_frame_size_enum)
 #define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \
 			_IOWR('V', 75, struct v4l2_subdev_frame_interval_enum)
+#define VIDIOC_SUBDEV_G_CROP	_IOWR('V', 59, struct v4l2_subdev_crop)
+#define VIDIOC_SUBDEV_S_CROP	_IOWR('V', 60, struct v4l2_subdev_crop)
 
 #endif
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 9c8bcd3..a02663e 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -442,6 +442,10 @@ struct v4l2_subdev_pad_ops {
 		       struct v4l2_subdev_format *format);
 	int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 		       struct v4l2_subdev_format *format);
+	int (*set_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_crop *crop);
+	int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_crop *crop);
 };
 
 struct v4l2_subdev_ops {
-- 
1.6.6.1