Linux Audio

Check our new training course

Loading...
v4.6
 
  1/*
  2 *	uvc_video.c  --  USB Video Class Gadget driver
  3 *
  4 *	Copyright (C) 2009-2010
  5 *	    Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  6 *
  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
  9 *	the Free Software Foundation; either version 2 of the License, or
 10 *	(at your option) any later version.
 11 */
 12
 13#include <linux/kernel.h>
 14#include <linux/device.h>
 15#include <linux/errno.h>
 16#include <linux/usb/ch9.h>
 17#include <linux/usb/gadget.h>
 18#include <linux/usb/video.h>
 19
 20#include <media/v4l2-dev.h>
 21
 22#include "uvc.h"
 23#include "uvc_queue.h"
 24#include "uvc_video.h"
 25
 26/* --------------------------------------------------------------------------
 27 * Video codecs
 28 */
 29
 30static int
 31uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,
 32		u8 *data, int len)
 33{
 34	data[0] = 2;
 35	data[1] = UVC_STREAM_EOH | video->fid;
 36
 37	if (buf->bytesused - video->queue.buf_used <= len - 2)
 38		data[1] |= UVC_STREAM_EOF;
 39
 40	return 2;
 41}
 42
 43static int
 44uvc_video_encode_data(struct uvc_video *video, struct uvc_buffer *buf,
 45		u8 *data, int len)
 46{
 47	struct uvc_video_queue *queue = &video->queue;
 48	unsigned int nbytes;
 49	void *mem;
 50
 51	/* Copy video data to the USB buffer. */
 52	mem = buf->mem + queue->buf_used;
 53	nbytes = min((unsigned int)len, buf->bytesused - queue->buf_used);
 54
 55	memcpy(data, mem, nbytes);
 56	queue->buf_used += nbytes;
 57
 58	return nbytes;
 59}
 60
 61static void
 62uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
 63		struct uvc_buffer *buf)
 64{
 65	void *mem = req->buf;
 66	int len = video->req_size;
 67	int ret;
 68
 69	/* Add a header at the beginning of the payload. */
 70	if (video->payload_size == 0) {
 71		ret = uvc_video_encode_header(video, buf, mem, len);
 72		video->payload_size += ret;
 73		mem += ret;
 74		len -= ret;
 75	}
 76
 77	/* Process video data. */
 78	len = min((int)(video->max_payload_size - video->payload_size), len);
 79	ret = uvc_video_encode_data(video, buf, mem, len);
 80
 81	video->payload_size += ret;
 82	len -= ret;
 83
 84	req->length = video->req_size - len;
 85	req->zero = video->payload_size == video->max_payload_size;
 86
 87	if (buf->bytesused == video->queue.buf_used) {
 88		video->queue.buf_used = 0;
 89		buf->state = UVC_BUF_STATE_DONE;
 90		uvcg_queue_next_buffer(&video->queue, buf);
 91		video->fid ^= UVC_STREAM_FID;
 92
 93		video->payload_size = 0;
 94	}
 95
 96	if (video->payload_size == video->max_payload_size ||
 97	    buf->bytesused == video->queue.buf_used)
 98		video->payload_size = 0;
 99}
100
101static void
102uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
103		struct uvc_buffer *buf)
104{
105	void *mem = req->buf;
106	int len = video->req_size;
107	int ret;
108
109	/* Add the header. */
110	ret = uvc_video_encode_header(video, buf, mem, len);
111	mem += ret;
112	len -= ret;
113
114	/* Process video data. */
115	ret = uvc_video_encode_data(video, buf, mem, len);
116	len -= ret;
117
118	req->length = video->req_size - len;
119
120	if (buf->bytesused == video->queue.buf_used) {
121		video->queue.buf_used = 0;
122		buf->state = UVC_BUF_STATE_DONE;
123		uvcg_queue_next_buffer(&video->queue, buf);
124		video->fid ^= UVC_STREAM_FID;
125	}
126}
127
128/* --------------------------------------------------------------------------
129 * Request handling
130 */
131
132/*
133 * I somehow feel that synchronisation won't be easy to achieve here. We have
134 * three events that control USB requests submission:
135 *
136 * - USB request completion: the completion handler will resubmit the request
137 *   if a video buffer is available.
138 *
139 * - USB interface setting selection: in response to a SET_INTERFACE request,
140 *   the handler will start streaming if a video buffer is available and if
141 *   video is not currently streaming.
142 *
143 * - V4L2 buffer queueing: the driver will start streaming if video is not
144 *   currently streaming.
145 *
146 * Race conditions between those 3 events might lead to deadlocks or other
147 * nasty side effects.
148 *
149 * The "video currently streaming" condition can't be detected by the irqqueue
150 * being empty, as a request can still be in flight. A separate "queue paused"
151 * flag is thus needed.
152 *
153 * The paused flag will be set when we try to retrieve the irqqueue head if the
154 * queue is empty, and cleared when we queue a buffer.
155 *
156 * The USB request completion handler will get the buffer at the irqqueue head
157 * under protection of the queue spinlock. If the queue is empty, the streaming
158 * paused flag will be set. Right after releasing the spinlock a userspace
159 * application can queue a buffer. The flag will then cleared, and the ioctl
160 * handler will restart the video stream.
161 */
162static void
163uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
164{
165	struct uvc_video *video = req->context;
166	struct uvc_video_queue *queue = &video->queue;
167	struct uvc_buffer *buf;
168	unsigned long flags;
169	int ret;
170
171	switch (req->status) {
172	case 0:
173		break;
174
175	case -ESHUTDOWN:	/* disconnect from host. */
176		printk(KERN_DEBUG "VS request cancelled.\n");
177		uvcg_queue_cancel(queue, 1);
178		goto requeue;
179
180	default:
181		printk(KERN_INFO "VS request completed with status %d.\n",
182			req->status);
 
183		uvcg_queue_cancel(queue, 0);
184		goto requeue;
185	}
186
187	spin_lock_irqsave(&video->queue.irqlock, flags);
188	buf = uvcg_queue_head(&video->queue);
189	if (buf == NULL) {
190		spin_unlock_irqrestore(&video->queue.irqlock, flags);
191		goto requeue;
192	}
193
194	video->encode(req, video, buf);
195
196	if ((ret = usb_ep_queue(ep, req, GFP_ATOMIC)) < 0) {
197		printk(KERN_INFO "Failed to queue request (%d).\n", ret);
198		usb_ep_set_halt(ep);
199		spin_unlock_irqrestore(&video->queue.irqlock, flags);
200		uvcg_queue_cancel(queue, 0);
201		goto requeue;
202	}
203	spin_unlock_irqrestore(&video->queue.irqlock, flags);
204
205	return;
206
207requeue:
208	spin_lock_irqsave(&video->req_lock, flags);
209	list_add_tail(&req->list, &video->req_free);
210	spin_unlock_irqrestore(&video->req_lock, flags);
 
 
211}
212
213static int
214uvc_video_free_requests(struct uvc_video *video)
215{
216	unsigned int i;
217
218	for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
219		if (video->req[i]) {
220			usb_ep_free_request(video->ep, video->req[i]);
221			video->req[i] = NULL;
222		}
223
224		if (video->req_buffer[i]) {
225			kfree(video->req_buffer[i]);
226			video->req_buffer[i] = NULL;
227		}
228	}
229
230	INIT_LIST_HEAD(&video->req_free);
231	video->req_size = 0;
232	return 0;
233}
234
235static int
236uvc_video_alloc_requests(struct uvc_video *video)
237{
238	unsigned int req_size;
239	unsigned int i;
240	int ret = -ENOMEM;
241
242	BUG_ON(video->req_size);
243
244	req_size = video->ep->maxpacket
245		 * max_t(unsigned int, video->ep->maxburst, 1)
246		 * (video->ep->mult + 1);
247
248	for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
249		video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
250		if (video->req_buffer[i] == NULL)
251			goto error;
252
253		video->req[i] = usb_ep_alloc_request(video->ep, GFP_KERNEL);
254		if (video->req[i] == NULL)
255			goto error;
256
257		video->req[i]->buf = video->req_buffer[i];
258		video->req[i]->length = 0;
259		video->req[i]->complete = uvc_video_complete;
260		video->req[i]->context = video;
261
262		list_add_tail(&video->req[i]->list, &video->req_free);
263	}
264
265	video->req_size = req_size;
266
267	return 0;
268
269error:
270	uvc_video_free_requests(video);
271	return ret;
272}
273
274/* --------------------------------------------------------------------------
275 * Video streaming
276 */
277
278/*
279 * uvcg_video_pump - Pump video data into the USB requests
280 *
281 * This function fills the available USB requests (listed in req_free) with
282 * video data from the queued buffers.
283 */
284int uvcg_video_pump(struct uvc_video *video)
285{
 
286	struct uvc_video_queue *queue = &video->queue;
287	struct usb_request *req;
288	struct uvc_buffer *buf;
289	unsigned long flags;
290	int ret;
291
292	/* FIXME TODO Race between uvcg_video_pump and requests completion
293	 * handler ???
294	 */
295
296	while (1) {
297		/* Retrieve the first available USB request, protected by the
298		 * request lock.
299		 */
300		spin_lock_irqsave(&video->req_lock, flags);
301		if (list_empty(&video->req_free)) {
302			spin_unlock_irqrestore(&video->req_lock, flags);
303			return 0;
304		}
305		req = list_first_entry(&video->req_free, struct usb_request,
306					list);
307		list_del(&req->list);
308		spin_unlock_irqrestore(&video->req_lock, flags);
309
310		/* Retrieve the first available video buffer and fill the
311		 * request, protected by the video queue irqlock.
312		 */
313		spin_lock_irqsave(&queue->irqlock, flags);
314		buf = uvcg_queue_head(queue);
315		if (buf == NULL) {
316			spin_unlock_irqrestore(&queue->irqlock, flags);
317			break;
318		}
319
320		video->encode(req, video, buf);
321
322		/* Queue the USB request */
323		ret = usb_ep_queue(video->ep, req, GFP_ATOMIC);
 
 
324		if (ret < 0) {
325			printk(KERN_INFO "Failed to queue request (%d)\n", ret);
326			usb_ep_set_halt(video->ep);
327			spin_unlock_irqrestore(&queue->irqlock, flags);
328			uvcg_queue_cancel(queue, 0);
329			break;
330		}
331		spin_unlock_irqrestore(&queue->irqlock, flags);
332	}
333
334	spin_lock_irqsave(&video->req_lock, flags);
335	list_add_tail(&req->list, &video->req_free);
336	spin_unlock_irqrestore(&video->req_lock, flags);
337	return 0;
338}
339
340/*
341 * Enable or disable the video stream.
342 */
343int uvcg_video_enable(struct uvc_video *video, int enable)
344{
345	unsigned int i;
346	int ret;
347
348	if (video->ep == NULL) {
349		printk(KERN_INFO "Video enable failed, device is "
350			"uninitialized.\n");
351		return -ENODEV;
352	}
353
354	if (!enable) {
 
 
 
355		for (i = 0; i < UVC_NUM_REQUESTS; ++i)
356			if (video->req[i])
357				usb_ep_dequeue(video->ep, video->req[i]);
358
359		uvc_video_free_requests(video);
360		uvcg_queue_enable(&video->queue, 0);
361		return 0;
362	}
363
364	if ((ret = uvcg_queue_enable(&video->queue, 1)) < 0)
365		return ret;
366
367	if ((ret = uvc_video_alloc_requests(video)) < 0)
368		return ret;
369
370	if (video->max_payload_size) {
371		video->encode = uvc_video_encode_bulk;
372		video->payload_size = 0;
373	} else
374		video->encode = uvc_video_encode_isoc;
375
376	return uvcg_video_pump(video);
 
 
377}
378
379/*
380 * Initialize the UVC video stream.
381 */
382int uvcg_video_init(struct uvc_video *video)
383{
384	INIT_LIST_HEAD(&video->req_free);
385	spin_lock_init(&video->req_lock);
 
386
 
387	video->fcc = V4L2_PIX_FMT_YUYV;
388	video->bpp = 16;
389	video->width = 320;
390	video->height = 240;
391	video->imagesize = 320 * 240 * 2;
392
393	/* Initialize the video buffers queue. */
394	uvcg_queue_init(&video->queue, V4L2_BUF_TYPE_VIDEO_OUTPUT,
395			&video->mutex);
396	return 0;
397}
398
v5.9
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 *	uvc_video.c  --  USB Video Class Gadget driver
  4 *
  5 *	Copyright (C) 2009-2010
  6 *	    Laurent Pinchart (laurent.pinchart@ideasonboard.com)
 
 
 
 
 
  7 */
  8
  9#include <linux/kernel.h>
 10#include <linux/device.h>
 11#include <linux/errno.h>
 12#include <linux/usb/ch9.h>
 13#include <linux/usb/gadget.h>
 14#include <linux/usb/video.h>
 15
 16#include <media/v4l2-dev.h>
 17
 18#include "uvc.h"
 19#include "uvc_queue.h"
 20#include "uvc_video.h"
 21
 22/* --------------------------------------------------------------------------
 23 * Video codecs
 24 */
 25
 26static int
 27uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,
 28		u8 *data, int len)
 29{
 30	data[0] = 2;
 31	data[1] = UVC_STREAM_EOH | video->fid;
 32
 33	if (buf->bytesused - video->queue.buf_used <= len - 2)
 34		data[1] |= UVC_STREAM_EOF;
 35
 36	return 2;
 37}
 38
 39static int
 40uvc_video_encode_data(struct uvc_video *video, struct uvc_buffer *buf,
 41		u8 *data, int len)
 42{
 43	struct uvc_video_queue *queue = &video->queue;
 44	unsigned int nbytes;
 45	void *mem;
 46
 47	/* Copy video data to the USB buffer. */
 48	mem = buf->mem + queue->buf_used;
 49	nbytes = min((unsigned int)len, buf->bytesused - queue->buf_used);
 50
 51	memcpy(data, mem, nbytes);
 52	queue->buf_used += nbytes;
 53
 54	return nbytes;
 55}
 56
 57static void
 58uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
 59		struct uvc_buffer *buf)
 60{
 61	void *mem = req->buf;
 62	int len = video->req_size;
 63	int ret;
 64
 65	/* Add a header at the beginning of the payload. */
 66	if (video->payload_size == 0) {
 67		ret = uvc_video_encode_header(video, buf, mem, len);
 68		video->payload_size += ret;
 69		mem += ret;
 70		len -= ret;
 71	}
 72
 73	/* Process video data. */
 74	len = min((int)(video->max_payload_size - video->payload_size), len);
 75	ret = uvc_video_encode_data(video, buf, mem, len);
 76
 77	video->payload_size += ret;
 78	len -= ret;
 79
 80	req->length = video->req_size - len;
 81	req->zero = video->payload_size == video->max_payload_size;
 82
 83	if (buf->bytesused == video->queue.buf_used) {
 84		video->queue.buf_used = 0;
 85		buf->state = UVC_BUF_STATE_DONE;
 86		uvcg_queue_next_buffer(&video->queue, buf);
 87		video->fid ^= UVC_STREAM_FID;
 88
 89		video->payload_size = 0;
 90	}
 91
 92	if (video->payload_size == video->max_payload_size ||
 93	    buf->bytesused == video->queue.buf_used)
 94		video->payload_size = 0;
 95}
 96
 97static void
 98uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
 99		struct uvc_buffer *buf)
100{
101	void *mem = req->buf;
102	int len = video->req_size;
103	int ret;
104
105	/* Add the header. */
106	ret = uvc_video_encode_header(video, buf, mem, len);
107	mem += ret;
108	len -= ret;
109
110	/* Process video data. */
111	ret = uvc_video_encode_data(video, buf, mem, len);
112	len -= ret;
113
114	req->length = video->req_size - len;
115
116	if (buf->bytesused == video->queue.buf_used) {
117		video->queue.buf_used = 0;
118		buf->state = UVC_BUF_STATE_DONE;
119		uvcg_queue_next_buffer(&video->queue, buf);
120		video->fid ^= UVC_STREAM_FID;
121	}
122}
123
124/* --------------------------------------------------------------------------
125 * Request handling
126 */
127
128static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req)
129{
130	int ret;
131
132	ret = usb_ep_queue(video->ep, req, GFP_ATOMIC);
133	if (ret < 0) {
134		uvcg_err(&video->uvc->func, "Failed to queue request (%d).\n",
135			 ret);
136
137		/* Isochronous endpoints can't be halted. */
138		if (usb_endpoint_xfer_bulk(video->ep->desc))
139			usb_ep_set_halt(video->ep);
140	}
141
142	return ret;
143}
144
 
 
 
 
 
 
 
 
 
 
 
 
 
145static void
146uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
147{
148	struct uvc_video *video = req->context;
149	struct uvc_video_queue *queue = &video->queue;
 
150	unsigned long flags;
 
151
152	switch (req->status) {
153	case 0:
154		break;
155
156	case -ESHUTDOWN:	/* disconnect from host. */
157		uvcg_dbg(&video->uvc->func, "VS request cancelled.\n");
158		uvcg_queue_cancel(queue, 1);
159		break;
160
161	default:
162		uvcg_info(&video->uvc->func,
163			  "VS request completed with status %d.\n",
164			  req->status);
165		uvcg_queue_cancel(queue, 0);
 
 
 
 
 
 
 
 
166	}
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168	spin_lock_irqsave(&video->req_lock, flags);
169	list_add_tail(&req->list, &video->req_free);
170	spin_unlock_irqrestore(&video->req_lock, flags);
171
172	schedule_work(&video->pump);
173}
174
175static int
176uvc_video_free_requests(struct uvc_video *video)
177{
178	unsigned int i;
179
180	for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
181		if (video->req[i]) {
182			usb_ep_free_request(video->ep, video->req[i]);
183			video->req[i] = NULL;
184		}
185
186		if (video->req_buffer[i]) {
187			kfree(video->req_buffer[i]);
188			video->req_buffer[i] = NULL;
189		}
190	}
191
192	INIT_LIST_HEAD(&video->req_free);
193	video->req_size = 0;
194	return 0;
195}
196
197static int
198uvc_video_alloc_requests(struct uvc_video *video)
199{
200	unsigned int req_size;
201	unsigned int i;
202	int ret = -ENOMEM;
203
204	BUG_ON(video->req_size);
205
206	req_size = video->ep->maxpacket
207		 * max_t(unsigned int, video->ep->maxburst, 1)
208		 * (video->ep->mult);
209
210	for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
211		video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
212		if (video->req_buffer[i] == NULL)
213			goto error;
214
215		video->req[i] = usb_ep_alloc_request(video->ep, GFP_KERNEL);
216		if (video->req[i] == NULL)
217			goto error;
218
219		video->req[i]->buf = video->req_buffer[i];
220		video->req[i]->length = 0;
221		video->req[i]->complete = uvc_video_complete;
222		video->req[i]->context = video;
223
224		list_add_tail(&video->req[i]->list, &video->req_free);
225	}
226
227	video->req_size = req_size;
228
229	return 0;
230
231error:
232	uvc_video_free_requests(video);
233	return ret;
234}
235
236/* --------------------------------------------------------------------------
237 * Video streaming
238 */
239
240/*
241 * uvcg_video_pump - Pump video data into the USB requests
242 *
243 * This function fills the available USB requests (listed in req_free) with
244 * video data from the queued buffers.
245 */
246static void uvcg_video_pump(struct work_struct *work)
247{
248	struct uvc_video *video = container_of(work, struct uvc_video, pump);
249	struct uvc_video_queue *queue = &video->queue;
250	struct usb_request *req;
251	struct uvc_buffer *buf;
252	unsigned long flags;
253	int ret;
254
 
 
 
 
255	while (1) {
256		/* Retrieve the first available USB request, protected by the
257		 * request lock.
258		 */
259		spin_lock_irqsave(&video->req_lock, flags);
260		if (list_empty(&video->req_free)) {
261			spin_unlock_irqrestore(&video->req_lock, flags);
262			return;
263		}
264		req = list_first_entry(&video->req_free, struct usb_request,
265					list);
266		list_del(&req->list);
267		spin_unlock_irqrestore(&video->req_lock, flags);
268
269		/* Retrieve the first available video buffer and fill the
270		 * request, protected by the video queue irqlock.
271		 */
272		spin_lock_irqsave(&queue->irqlock, flags);
273		buf = uvcg_queue_head(queue);
274		if (buf == NULL) {
275			spin_unlock_irqrestore(&queue->irqlock, flags);
276			break;
277		}
278
279		video->encode(req, video, buf);
280
281		/* Queue the USB request */
282		ret = uvcg_video_ep_queue(video, req);
283		spin_unlock_irqrestore(&queue->irqlock, flags);
284
285		if (ret < 0) {
 
 
 
286			uvcg_queue_cancel(queue, 0);
287			break;
288		}
 
289	}
290
291	spin_lock_irqsave(&video->req_lock, flags);
292	list_add_tail(&req->list, &video->req_free);
293	spin_unlock_irqrestore(&video->req_lock, flags);
294	return;
295}
296
297/*
298 * Enable or disable the video stream.
299 */
300int uvcg_video_enable(struct uvc_video *video, int enable)
301{
302	unsigned int i;
303	int ret;
304
305	if (video->ep == NULL) {
306		uvcg_info(&video->uvc->func,
307			  "Video enable failed, device is uninitialized.\n");
308		return -ENODEV;
309	}
310
311	if (!enable) {
312		cancel_work_sync(&video->pump);
313		uvcg_queue_cancel(&video->queue, 0);
314
315		for (i = 0; i < UVC_NUM_REQUESTS; ++i)
316			if (video->req[i])
317				usb_ep_dequeue(video->ep, video->req[i]);
318
319		uvc_video_free_requests(video);
320		uvcg_queue_enable(&video->queue, 0);
321		return 0;
322	}
323
324	if ((ret = uvcg_queue_enable(&video->queue, 1)) < 0)
325		return ret;
326
327	if ((ret = uvc_video_alloc_requests(video)) < 0)
328		return ret;
329
330	if (video->max_payload_size) {
331		video->encode = uvc_video_encode_bulk;
332		video->payload_size = 0;
333	} else
334		video->encode = uvc_video_encode_isoc;
335
336	schedule_work(&video->pump);
337
338	return ret;
339}
340
341/*
342 * Initialize the UVC video stream.
343 */
344int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
345{
346	INIT_LIST_HEAD(&video->req_free);
347	spin_lock_init(&video->req_lock);
348	INIT_WORK(&video->pump, uvcg_video_pump);
349
350	video->uvc = uvc;
351	video->fcc = V4L2_PIX_FMT_YUYV;
352	video->bpp = 16;
353	video->width = 320;
354	video->height = 240;
355	video->imagesize = 320 * 240 * 2;
356
357	/* Initialize the video buffers queue. */
358	uvcg_queue_init(&video->queue, V4L2_BUF_TYPE_VIDEO_OUTPUT,
359			&video->mutex);
360	return 0;
361}
362