aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc/uvc_video.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@skynet.be>2008-12-28 20:32:29 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:40:32 -0500
commitff924203c9e4a5bc218143bc37182851185f4e5f (patch)
tree11ed46e7426ffc00bf016c3b67b26ba26f338c54 /drivers/media/video/uvc/uvc_video.c
parent538e7a004bf960c96c7e9eb836b59989eb5f5b7f (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_video.c')
-rw-r--r--drivers/media/video/uvc/uvc_video.c102
1 files changed, 95 insertions, 7 deletions
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 6d0ac3be8191..e7c31995527f 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -453,6 +453,34 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
453 } 453 }
454} 454}
455 455
456static int uvc_video_encode_header(struct uvc_video_device *video,
457 struct uvc_buffer *buf, __u8 *data, int len)
458{
459 data[0] = 2; /* Header length */
460 data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF
461 | (video->last_fid & UVC_STREAM_FID);
462 return 2;
463}
464
465static int uvc_video_encode_data(struct uvc_video_device *video,
466 struct uvc_buffer *buf, __u8 *data, int len)
467{
468 struct uvc_video_queue *queue = &video->queue;
469 unsigned int nbytes;
470 void *mem;
471
472 /* Copy video data to the URB buffer. */
473 mem = queue->mem + buf->buf.m.offset + queue->buf_used;
474 nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used);
475 nbytes = min(video->bulk.max_payload_size - video->bulk.payload_size,
476 nbytes);
477 memcpy(data, mem, nbytes);
478
479 queue->buf_used += nbytes;
480
481 return nbytes;
482}
483
456/* ------------------------------------------------------------------------ 484/* ------------------------------------------------------------------------
457 * URB handling 485 * URB handling
458 */ 486 */
@@ -559,6 +587,48 @@ static void uvc_video_decode_bulk(struct urb *urb,
559 } 587 }
560} 588}
561 589
590static void uvc_video_encode_bulk(struct urb *urb,
591 struct uvc_video_device *video, struct uvc_buffer *buf)
592{
593 u8 *mem = urb->transfer_buffer;
594 int len = video->urb_size, ret;
595
596 if (buf == NULL) {
597 urb->transfer_buffer_length = 0;
598 return;
599 }
600
601 /* If the URB is the first of its payload, add the header. */
602 if (video->bulk.header_size == 0) {
603 ret = uvc_video_encode_header(video, buf, mem, len);
604 video->bulk.header_size = ret;
605 video->bulk.payload_size += ret;
606 mem += ret;
607 len -= ret;
608 }
609
610 /* Process video data. */
611 ret = uvc_video_encode_data(video, buf, mem, len);
612
613 video->bulk.payload_size += ret;
614 len -= ret;
615
616 if (buf->buf.bytesused == video->queue.buf_used ||
617 video->bulk.payload_size == video->bulk.max_payload_size) {
618 if (buf->buf.bytesused == video->queue.buf_used) {
619 video->queue.buf_used = 0;
620 buf->state = UVC_BUF_STATE_DONE;
621 uvc_queue_next_buffer(&video->queue, buf);
622 video->last_fid ^= UVC_STREAM_FID;
623 }
624
625 video->bulk.header_size = 0;
626 video->bulk.payload_size = 0;
627 }
628
629 urb->transfer_buffer_length = video->urb_size - len;
630}
631
562static void uvc_video_complete(struct urb *urb) 632static void uvc_video_complete(struct urb *urb)
563{ 633{
564 struct uvc_video_device *video = urb->context; 634 struct uvc_video_device *video = urb->context;
@@ -756,7 +826,15 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
756 if (uvc_alloc_urb_buffers(video, size) < 0) 826 if (uvc_alloc_urb_buffers(video, size) < 0)
757 return -ENOMEM; 827 return -ENOMEM;
758 828
759 pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress); 829 if (usb_endpoint_dir_in(&ep->desc))
830 pipe = usb_rcvbulkpipe(video->dev->udev,
831 ep->desc.bEndpointAddress);
832 else
833 pipe = usb_sndbulkpipe(video->dev->udev,
834 ep->desc.bEndpointAddress);
835
836 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
837 size = 0;
760 838
761 for (i = 0; i < UVC_URBS; ++i) { 839 for (i = 0; i < UVC_URBS; ++i) {
762 urb = usb_alloc_urb(0, gfp_flags); 840 urb = usb_alloc_urb(0, gfp_flags);
@@ -977,12 +1055,22 @@ int uvc_video_init(struct uvc_video_device *video)
977 atomic_set(&video->active, 0); 1055 atomic_set(&video->active, 0);
978 1056
979 /* Select the video decoding function */ 1057 /* Select the video decoding function */
980 if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT) 1058 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
981 video->decode = uvc_video_decode_isight; 1059 if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
982 else if (video->streaming->intf->num_altsetting > 1) 1060 video->decode = uvc_video_decode_isight;
983 video->decode = uvc_video_decode_isoc; 1061 else if (video->streaming->intf->num_altsetting > 1)
984 else 1062 video->decode = uvc_video_decode_isoc;
985 video->decode = uvc_video_decode_bulk; 1063 else
1064 video->decode = uvc_video_decode_bulk;
1065 } else {
1066 if (video->streaming->intf->num_altsetting == 1)
1067 video->decode = uvc_video_encode_bulk;
1068 else {
1069 uvc_printk(KERN_INFO, "Isochronous endpoints are not "
1070 "supported for video output devices.\n");
1071 return -EINVAL;
1072 }
1073 }
986 1074
987 return 0; 1075 return 0;
988} 1076}