diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2010-03-15 19:26:04 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-22 03:53:31 -0400 |
commit | 333c8b97785d5afd5085ba3720b4d259623290f6 (patch) | |
tree | 3cba92af1765957c68f74042dea1873481554ede /drivers | |
parent | d3a7ed99759b18e4fd19b8ddd226f8085b8bd975 (diff) |
[media] v4l: v4l2_subdev userspace format API
Add a userspace API to get, set and enumerate the media format on a
subdev pad.
The format at the output of a subdev usually depends on the format at
its input(s). The try format operation is thus not suitable for probing
format at individual pads, as it can't modify the device state and thus
can't remember the format tried at the input to compute the output
format.
To fix the problem, pass an extra argument to the get/set format
operations to select the 'try' or 'active' format.
The try format is used when probing the subdev. Setting the try format
must not change the device configuration but can store data for later
reuse. Data storage is provided at the file-handle level so applications
probing the subdev concurently won't interfere with each other.
The active format is used when configuring the subdev. It's identical to
the format handled by the usual get/set operations.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/v4l2-subdev.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c index bc763db385df..207cc5cceb29 100644 --- a/drivers/media/video/v4l2-subdev.c +++ b/drivers/media/video/v4l2-subdev.c | |||
@@ -149,6 +149,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
149 | struct video_device *vdev = video_devdata(file); | 149 | struct video_device *vdev = video_devdata(file); |
150 | struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); | 150 | struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); |
151 | struct v4l2_fh *vfh = file->private_data; | 151 | struct v4l2_fh *vfh = file->private_data; |
152 | #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) | ||
153 | struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); | ||
154 | #endif | ||
152 | 155 | ||
153 | switch (cmd) { | 156 | switch (cmd) { |
154 | case VIDIOC_QUERYCTRL: | 157 | case VIDIOC_QUERYCTRL: |
@@ -183,7 +186,53 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
183 | 186 | ||
184 | case VIDIOC_UNSUBSCRIBE_EVENT: | 187 | case VIDIOC_UNSUBSCRIBE_EVENT: |
185 | return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg); | 188 | return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg); |
189 | #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) | ||
190 | case VIDIOC_SUBDEV_G_FMT: { | ||
191 | struct v4l2_subdev_format *format = arg; | ||
192 | |||
193 | if (format->which != V4L2_SUBDEV_FORMAT_TRY && | ||
194 | format->which != V4L2_SUBDEV_FORMAT_ACTIVE) | ||
195 | return -EINVAL; | ||
196 | |||
197 | if (format->pad >= sd->entity.num_pads) | ||
198 | return -EINVAL; | ||
199 | |||
200 | return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format); | ||
201 | } | ||
202 | |||
203 | case VIDIOC_SUBDEV_S_FMT: { | ||
204 | struct v4l2_subdev_format *format = arg; | ||
205 | |||
206 | if (format->which != V4L2_SUBDEV_FORMAT_TRY && | ||
207 | format->which != V4L2_SUBDEV_FORMAT_ACTIVE) | ||
208 | return -EINVAL; | ||
209 | |||
210 | if (format->pad >= sd->entity.num_pads) | ||
211 | return -EINVAL; | ||
186 | 212 | ||
213 | return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format); | ||
214 | } | ||
215 | |||
216 | case VIDIOC_SUBDEV_ENUM_MBUS_CODE: { | ||
217 | struct v4l2_subdev_mbus_code_enum *code = arg; | ||
218 | |||
219 | if (code->pad >= sd->entity.num_pads) | ||
220 | return -EINVAL; | ||
221 | |||
222 | return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh, | ||
223 | code); | ||
224 | } | ||
225 | |||
226 | case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: { | ||
227 | struct v4l2_subdev_frame_size_enum *fse = arg; | ||
228 | |||
229 | if (fse->pad >= sd->entity.num_pads) | ||
230 | return -EINVAL; | ||
231 | |||
232 | return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh, | ||
233 | fse); | ||
234 | } | ||
235 | #endif | ||
187 | default: | 236 | default: |
188 | return -ENOIOCTLCMD; | 237 | return -ENOIOCTLCMD; |
189 | } | 238 | } |