aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc/uvc_queue.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_queue.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_queue.c')
-rw-r--r--drivers/media/video/uvc/uvc_queue.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 5646a6a32939..42546342e97d 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -79,12 +79,13 @@
79 * 79 *
80 */ 80 */
81 81
82void uvc_queue_init(struct uvc_video_queue *queue) 82void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
83{ 83{
84 mutex_init(&queue->mutex); 84 mutex_init(&queue->mutex);
85 spin_lock_init(&queue->irqlock); 85 spin_lock_init(&queue->irqlock);
86 INIT_LIST_HEAD(&queue->mainqueue); 86 INIT_LIST_HEAD(&queue->mainqueue);
87 INIT_LIST_HEAD(&queue->irqqueue); 87 INIT_LIST_HEAD(&queue->irqqueue);
88 queue->type = type;
88} 89}
89 90
90/* 91/*
@@ -132,7 +133,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
132 queue->buffer[i].buf.index = i; 133 queue->buffer[i].buf.index = i;
133 queue->buffer[i].buf.m.offset = i * bufsize; 134 queue->buffer[i].buf.m.offset = i * bufsize;
134 queue->buffer[i].buf.length = buflength; 135 queue->buffer[i].buf.length = buflength;
135 queue->buffer[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 136 queue->buffer[i].buf.type = queue->type;
136 queue->buffer[i].buf.sequence = 0; 137 queue->buffer[i].buf.sequence = 0;
137 queue->buffer[i].buf.field = V4L2_FIELD_NONE; 138 queue->buffer[i].buf.field = V4L2_FIELD_NONE;
138 queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; 139 queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP;
@@ -226,7 +227,7 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
226 227
227 uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index); 228 uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index);
228 229
229 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 230 if (v4l2_buf->type != queue->type ||
230 v4l2_buf->memory != V4L2_MEMORY_MMAP) { 231 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
231 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " 232 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
232 "and/or memory (%u).\n", v4l2_buf->type, 233 "and/or memory (%u).\n", v4l2_buf->type,
@@ -249,6 +250,13 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
249 goto done; 250 goto done;
250 } 251 }
251 252
253 if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
254 v4l2_buf->bytesused > buf->buf.length) {
255 uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n");
256 ret = -EINVAL;
257 goto done;
258 }
259
252 spin_lock_irqsave(&queue->irqlock, flags); 260 spin_lock_irqsave(&queue->irqlock, flags);
253 if (queue->flags & UVC_QUEUE_DISCONNECTED) { 261 if (queue->flags & UVC_QUEUE_DISCONNECTED) {
254 spin_unlock_irqrestore(&queue->irqlock, flags); 262 spin_unlock_irqrestore(&queue->irqlock, flags);
@@ -256,7 +264,11 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
256 goto done; 264 goto done;
257 } 265 }
258 buf->state = UVC_BUF_STATE_QUEUED; 266 buf->state = UVC_BUF_STATE_QUEUED;
259 buf->buf.bytesused = 0; 267 if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
268 buf->buf.bytesused = 0;
269 else
270 buf->buf.bytesused = v4l2_buf->bytesused;
271
260 list_add_tail(&buf->stream, &queue->mainqueue); 272 list_add_tail(&buf->stream, &queue->mainqueue);
261 list_add_tail(&buf->queue, &queue->irqqueue); 273 list_add_tail(&buf->queue, &queue->irqqueue);
262 spin_unlock_irqrestore(&queue->irqlock, flags); 274 spin_unlock_irqrestore(&queue->irqlock, flags);
@@ -289,7 +301,7 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue,
289 struct uvc_buffer *buf; 301 struct uvc_buffer *buf;
290 int ret = 0; 302 int ret = 0;
291 303
292 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 304 if (v4l2_buf->type != queue->type ||
293 v4l2_buf->memory != V4L2_MEMORY_MMAP) { 305 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
294 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " 306 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
295 "and/or memory (%u).\n", v4l2_buf->type, 307 "and/or memory (%u).\n", v4l2_buf->type,
@@ -397,6 +409,7 @@ int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
397 } 409 }
398 queue->sequence = 0; 410 queue->sequence = 0;
399 queue->flags |= UVC_QUEUE_STREAMING; 411 queue->flags |= UVC_QUEUE_STREAMING;
412 queue->buf_used = 0;
400 } else { 413 } else {
401 uvc_queue_cancel(queue, 0); 414 uvc_queue_cancel(queue, 0);
402 INIT_LIST_HEAD(&queue->mainqueue); 415 INIT_LIST_HEAD(&queue->mainqueue);