diff options
author | Laurent Pinchart <laurent.pinchart@skynet.be> | 2008-12-28 20:32:29 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:40:32 -0500 |
commit | ff924203c9e4a5bc218143bc37182851185f4e5f (patch) | |
tree | 11ed46e7426ffc00bf016c3b67b26ba26f338c54 /drivers/media/video/uvc/uvc_v4l2.c | |
parent | 538e7a004bf960c96c7e9eb836b59989eb5f5b7f (diff) |
V4L/DVB (10104): uvcvideo: Add support for video output devices
Extend the range of supported UVC devices by allowing video output devices
matching the following structure:
TT_STREAMING -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> OTT_*
Video output devices are reported with the V4L2_CAP_VIDEO_OUTPUT capability
flag and are subject to the same restrictions as video input devices.
Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/uvc/uvc_v4l2.c')
-rw-r--r-- | drivers/media/video/uvc/uvc_v4l2.c | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 2e1fd1b2a619..afcc6934559e 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
@@ -110,7 +110,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video, | |||
110 | int ret = 0; | 110 | int ret = 0; |
111 | __u8 *fcc; | 111 | __u8 *fcc; |
112 | 112 | ||
113 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 113 | if (fmt->type != video->streaming->type) |
114 | return -EINVAL; | 114 | return -EINVAL; |
115 | 115 | ||
116 | fcc = (__u8 *)&fmt->fmt.pix.pixelformat; | 116 | fcc = (__u8 *)&fmt->fmt.pix.pixelformat; |
@@ -216,7 +216,7 @@ static int uvc_v4l2_get_format(struct uvc_video_device *video, | |||
216 | struct uvc_format *format = video->streaming->cur_format; | 216 | struct uvc_format *format = video->streaming->cur_format; |
217 | struct uvc_frame *frame = video->streaming->cur_frame; | 217 | struct uvc_frame *frame = video->streaming->cur_frame; |
218 | 218 | ||
219 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 219 | if (fmt->type != video->streaming->type) |
220 | return -EINVAL; | 220 | return -EINVAL; |
221 | 221 | ||
222 | if (format == NULL || frame == NULL) | 222 | if (format == NULL || frame == NULL) |
@@ -242,7 +242,7 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video, | |||
242 | struct uvc_frame *frame; | 242 | struct uvc_frame *frame; |
243 | int ret; | 243 | int ret; |
244 | 244 | ||
245 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 245 | if (fmt->type != video->streaming->type) |
246 | return -EINVAL; | 246 | return -EINVAL; |
247 | 247 | ||
248 | if (uvc_queue_streaming(&video->queue)) | 248 | if (uvc_queue_streaming(&video->queue)) |
@@ -264,7 +264,7 @@ static int uvc_v4l2_get_streamparm(struct uvc_video_device *video, | |||
264 | { | 264 | { |
265 | uint32_t numerator, denominator; | 265 | uint32_t numerator, denominator; |
266 | 266 | ||
267 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 267 | if (parm->type != video->streaming->type) |
268 | return -EINVAL; | 268 | return -EINVAL; |
269 | 269 | ||
270 | numerator = video->streaming->ctrl.dwFrameInterval; | 270 | numerator = video->streaming->ctrl.dwFrameInterval; |
@@ -272,13 +272,21 @@ static int uvc_v4l2_get_streamparm(struct uvc_video_device *video, | |||
272 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); | 272 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); |
273 | 273 | ||
274 | memset(parm, 0, sizeof *parm); | 274 | memset(parm, 0, sizeof *parm); |
275 | parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 275 | parm->type = video->streaming->type; |
276 | parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | 276 | |
277 | parm->parm.capture.capturemode = 0; | 277 | if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
278 | parm->parm.capture.timeperframe.numerator = numerator; | 278 | parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; |
279 | parm->parm.capture.timeperframe.denominator = denominator; | 279 | parm->parm.capture.capturemode = 0; |
280 | parm->parm.capture.extendedmode = 0; | 280 | parm->parm.capture.timeperframe.numerator = numerator; |
281 | parm->parm.capture.readbuffers = 0; | 281 | parm->parm.capture.timeperframe.denominator = denominator; |
282 | parm->parm.capture.extendedmode = 0; | ||
283 | parm->parm.capture.readbuffers = 0; | ||
284 | } else { | ||
285 | parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; | ||
286 | parm->parm.output.outputmode = 0; | ||
287 | parm->parm.output.timeperframe.numerator = numerator; | ||
288 | parm->parm.output.timeperframe.denominator = denominator; | ||
289 | } | ||
282 | 290 | ||
283 | return 0; | 291 | return 0; |
284 | } | 292 | } |
@@ -288,24 +296,27 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, | |||
288 | { | 296 | { |
289 | struct uvc_frame *frame = video->streaming->cur_frame; | 297 | struct uvc_frame *frame = video->streaming->cur_frame; |
290 | struct uvc_streaming_control probe; | 298 | struct uvc_streaming_control probe; |
299 | struct v4l2_fract timeperframe; | ||
291 | uint32_t interval; | 300 | uint32_t interval; |
292 | int ret; | 301 | int ret; |
293 | 302 | ||
294 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 303 | if (parm->type != video->streaming->type) |
295 | return -EINVAL; | 304 | return -EINVAL; |
296 | 305 | ||
297 | if (uvc_queue_streaming(&video->queue)) | 306 | if (uvc_queue_streaming(&video->queue)) |
298 | return -EBUSY; | 307 | return -EBUSY; |
299 | 308 | ||
309 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
310 | timeperframe = parm->parm.capture.timeperframe; | ||
311 | else | ||
312 | timeperframe = parm->parm.output.timeperframe; | ||
313 | |||
300 | memcpy(&probe, &video->streaming->ctrl, sizeof probe); | 314 | memcpy(&probe, &video->streaming->ctrl, sizeof probe); |
301 | interval = uvc_fraction_to_interval( | 315 | interval = uvc_fraction_to_interval(timeperframe.numerator, |
302 | parm->parm.capture.timeperframe.numerator, | 316 | timeperframe.denominator); |
303 | parm->parm.capture.timeperframe.denominator); | ||
304 | 317 | ||
305 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", | 318 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", |
306 | parm->parm.capture.timeperframe.numerator, | 319 | timeperframe.numerator, timeperframe.denominator, interval); |
307 | parm->parm.capture.timeperframe.denominator, | ||
308 | interval); | ||
309 | probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); | 320 | probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); |
310 | 321 | ||
311 | /* Probe the device with the new settings. */ | 322 | /* Probe the device with the new settings. */ |
@@ -315,11 +326,15 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, | |||
315 | memcpy(&video->streaming->ctrl, &probe, sizeof probe); | 326 | memcpy(&video->streaming->ctrl, &probe, sizeof probe); |
316 | 327 | ||
317 | /* Return the actual frame period. */ | 328 | /* Return the actual frame period. */ |
318 | parm->parm.capture.timeperframe.numerator = probe.dwFrameInterval; | 329 | timeperframe.numerator = probe.dwFrameInterval; |
319 | parm->parm.capture.timeperframe.denominator = 10000000; | 330 | timeperframe.denominator = 10000000; |
320 | uvc_simplify_fraction(&parm->parm.capture.timeperframe.numerator, | 331 | uvc_simplify_fraction(&timeperframe.numerator, |
321 | &parm->parm.capture.timeperframe.denominator, | 332 | &timeperframe.denominator, 8, 333); |
322 | 8, 333); | 333 | |
334 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
335 | parm->parm.capture.timeperframe = timeperframe; | ||
336 | else | ||
337 | parm->parm.output.timeperframe = timeperframe; | ||
323 | 338 | ||
324 | return 0; | 339 | return 0; |
325 | } | 340 | } |
@@ -476,8 +491,12 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
476 | strncpy(cap->bus_info, video->dev->udev->bus->bus_name, | 491 | strncpy(cap->bus_info, video->dev->udev->bus->bus_name, |
477 | sizeof cap->bus_info); | 492 | sizeof cap->bus_info); |
478 | cap->version = DRIVER_VERSION_NUMBER; | 493 | cap->version = DRIVER_VERSION_NUMBER; |
479 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 494 | if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
480 | | V4L2_CAP_STREAMING; | 495 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
496 | | V4L2_CAP_STREAMING; | ||
497 | else | ||
498 | cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | ||
499 | | V4L2_CAP_STREAMING; | ||
481 | break; | 500 | break; |
482 | } | 501 | } |
483 | 502 | ||
@@ -655,7 +674,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
655 | struct v4l2_fmtdesc *fmt = arg; | 674 | struct v4l2_fmtdesc *fmt = arg; |
656 | struct uvc_format *format; | 675 | struct uvc_format *format; |
657 | 676 | ||
658 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | 677 | if (fmt->type != video->streaming->type || |
659 | fmt->index >= video->streaming->nformats) | 678 | fmt->index >= video->streaming->nformats) |
660 | return -EINVAL; | 679 | return -EINVAL; |
661 | 680 | ||
@@ -794,7 +813,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
794 | struct v4l2_cropcap *ccap = arg; | 813 | struct v4l2_cropcap *ccap = arg; |
795 | struct uvc_frame *frame = video->streaming->cur_frame; | 814 | struct uvc_frame *frame = video->streaming->cur_frame; |
796 | 815 | ||
797 | if (ccap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 816 | if (ccap->type != video->streaming->type) |
798 | return -EINVAL; | 817 | return -EINVAL; |
799 | 818 | ||
800 | ccap->bounds.left = 0; | 819 | ccap->bounds.left = 0; |
@@ -820,7 +839,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
820 | unsigned int bufsize = | 839 | unsigned int bufsize = |
821 | video->streaming->ctrl.dwMaxVideoFrameSize; | 840 | video->streaming->ctrl.dwMaxVideoFrameSize; |
822 | 841 | ||
823 | if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | 842 | if (rb->type != video->streaming->type || |
824 | rb->memory != V4L2_MEMORY_MMAP) | 843 | rb->memory != V4L2_MEMORY_MMAP) |
825 | return -EINVAL; | 844 | return -EINVAL; |
826 | 845 | ||
@@ -840,7 +859,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
840 | { | 859 | { |
841 | struct v4l2_buffer *buf = arg; | 860 | struct v4l2_buffer *buf = arg; |
842 | 861 | ||
843 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 862 | if (buf->type != video->streaming->type) |
844 | return -EINVAL; | 863 | return -EINVAL; |
845 | 864 | ||
846 | if (!uvc_has_privileges(handle)) | 865 | if (!uvc_has_privileges(handle)) |
@@ -866,7 +885,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
866 | { | 885 | { |
867 | int *type = arg; | 886 | int *type = arg; |
868 | 887 | ||
869 | if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 888 | if (*type != video->streaming->type) |
870 | return -EINVAL; | 889 | return -EINVAL; |
871 | 890 | ||
872 | if (!uvc_has_privileges(handle)) | 891 | if (!uvc_has_privileges(handle)) |
@@ -881,7 +900,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
881 | { | 900 | { |
882 | int *type = arg; | 901 | int *type = arg; |
883 | 902 | ||
884 | if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 903 | if (*type != video->streaming->type) |
885 | return -EINVAL; | 904 | return -EINVAL; |
886 | 905 | ||
887 | if (!uvc_has_privileges(handle)) | 906 | if (!uvc_has_privileges(handle)) |