aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc/uvc_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/uvc/uvc_video.c')
-rw-r--r--drivers/media/video/uvc/uvc_video.c52
1 files changed, 47 insertions, 5 deletions
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index e27cf0d3b6d9..5555f0102838 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * uvc_video.c -- USB Video Class driver - Video handling 2 * uvc_video.c -- USB Video Class driver - Video handling
3 * 3 *
4 * Copyright (C) 2005-2009 4 * Copyright (C) 2005-2010
5 * Laurent Pinchart (laurent.pinchart@skynet.be) 5 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -45,6 +45,30 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
45 unit << 8 | intfnum, data, size, timeout); 45 unit << 8 | intfnum, data, size, timeout);
46} 46}
47 47
48static const char *uvc_query_name(__u8 query)
49{
50 switch (query) {
51 case UVC_SET_CUR:
52 return "SET_CUR";
53 case UVC_GET_CUR:
54 return "GET_CUR";
55 case UVC_GET_MIN:
56 return "GET_MIN";
57 case UVC_GET_MAX:
58 return "GET_MAX";
59 case UVC_GET_RES:
60 return "GET_RES";
61 case UVC_GET_LEN:
62 return "GET_LEN";
63 case UVC_GET_INFO:
64 return "GET_INFO";
65 case UVC_GET_DEF:
66 return "GET_DEF";
67 default:
68 return "<invalid>";
69 }
70}
71
48int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, 72int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
49 __u8 intfnum, __u8 cs, void *data, __u16 size) 73 __u8 intfnum, __u8 cs, void *data, __u16 size)
50{ 74{
@@ -53,9 +77,9 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
53 ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size, 77 ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
54 UVC_CTRL_CONTROL_TIMEOUT); 78 UVC_CTRL_CONTROL_TIMEOUT);
55 if (ret != size) { 79 if (ret != size) {
56 uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u " 80 uvc_printk(KERN_ERR, "Failed to query (%s) UVC control %u on "
57 "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret, 81 "unit %u: %d (exp. %u).\n", uvc_query_name(query), cs,
58 size); 82 unit, ret, size);
59 return -EIO; 83 return -EIO;
60 } 84 }
61 85
@@ -114,6 +138,15 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
114 bandwidth /= 8; 138 bandwidth /= 8;
115 bandwidth += 12; 139 bandwidth += 12;
116 140
141 /* The bandwidth estimate is too low for many cameras. Don't use
142 * maximum packet sizes lower than 1024 bytes to try and work
143 * around the problem. According to measurements done on two
144 * different camera models, the value is high enough to get most
145 * resolutions working while not preventing two simultaneous
146 * VGA streams at 15 fps.
147 */
148 bandwidth = max_t(u32, bandwidth, 1024);
149
117 ctrl->dwMaxPayloadTransferSize = bandwidth; 150 ctrl->dwMaxPayloadTransferSize = bandwidth;
118 } 151 }
119} 152}
@@ -394,6 +427,12 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
394 427
395 fid = data[1] & UVC_STREAM_FID; 428 fid = data[1] & UVC_STREAM_FID;
396 429
430 /* Increase the sequence number regardless of any buffer states, so
431 * that discontinuous sequence numbers always indicate lost frames.
432 */
433 if (stream->last_fid != fid)
434 stream->sequence++;
435
397 /* Store the payload FID bit and return immediately when the buffer is 436 /* Store the payload FID bit and return immediately when the buffer is
398 * NULL. 437 * NULL.
399 */ 438 */
@@ -427,6 +466,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
427 else 466 else
428 ktime_get_real_ts(&ts); 467 ktime_get_real_ts(&ts);
429 468
469 buf->buf.sequence = stream->sequence;
430 buf->buf.timestamp.tv_sec = ts.tv_sec; 470 buf->buf.timestamp.tv_sec = ts.tv_sec;
431 buf->buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC; 471 buf->buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
432 472
@@ -688,6 +728,7 @@ static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream,
688 if (buf->buf.bytesused == stream->queue.buf_used) { 728 if (buf->buf.bytesused == stream->queue.buf_used) {
689 stream->queue.buf_used = 0; 729 stream->queue.buf_used = 0;
690 buf->state = UVC_BUF_STATE_READY; 730 buf->state = UVC_BUF_STATE_READY;
731 buf->buf.sequence = ++stream->sequence;
691 uvc_queue_next_buffer(&stream->queue, buf); 732 uvc_queue_next_buffer(&stream->queue, buf);
692 stream->last_fid ^= UVC_STREAM_FID; 733 stream->last_fid ^= UVC_STREAM_FID;
693 } 734 }
@@ -946,6 +987,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
946 unsigned int i; 987 unsigned int i;
947 int ret; 988 int ret;
948 989
990 stream->sequence = -1;
949 stream->last_fid = -1; 991 stream->last_fid = -1;
950 stream->bulk.header_size = 0; 992 stream->bulk.header_size = 0;
951 stream->bulk.skip_payload = 0; 993 stream->bulk.skip_payload = 0;