Added UVC emulated device.
[qemu/v4l2.git] / hw / usb-uvc.c
blobb711f51c8fd9335ff5d68f4e87a3e37705eaf7c8
1 /*
2 * USB Video Class Device emulation.
4 * Copyright (c) 2010 Claunia.com
5 * Written by Natalia Portillo <natalia@claunia.com>
7 * Based on hw/usb-hid.c:
8 * Copyright (c) 2005 Fabrice Bellard
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation in its version 2.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "hw.h"
24 #include "console.h"
25 #include "usb.h"
26 #include "qemu-error.h"
27 #include <stdio.h>
28 #include <fcntl.h>
29 #include <errno.h>
30 // V4L2 ioctls
31 #include <sys/ioctl.h>
32 #include <linux/videodev2.h>
34 #define DEBUG_UVC
36 #ifdef DEBUG_UVC
37 #define DPRINTF(fmt, ...) \
38 do { printf("usb-uvc: " fmt , ## __VA_ARGS__); } while (0)
39 #else
40 #define DPRINTF(fmt, ...) do {} while(0)
41 #endif
43 /* USB Video Class Request codes */
44 #define USB_UVC_RC_UNDEFINED 0x00
45 #define USB_UVC_SET_CUR 0x01
46 #define USB_UVC_GET_CUR 0x81
47 #define USB_UVC_GET_MIN 0x82
48 #define USB_UVC_GET_MAX 0x83
49 #define USB_UVC_GET_RES 0x84
50 #define USB_UVC_GET_LEN 0x85
51 #define USB_UVC_GET_INFO 0x86
52 #define USB_UVC_GET_DEF 0x87
54 /* USB Video Class Request types */
55 #define UVCSetVideoControl 0x2100
56 #define UVCSetVideoStreaming 0x2200
57 #define UVCGetVideoControl 0xA100
58 #define UVCGetVideoStreaming 0xA200
60 typedef struct USBUVCState {
61 USBDevice dev;
62 char current_input;
63 char *v4l2_device;
64 } USBUVCState;
66 static int v4l2_fd;
67 static char *frame;
68 static char *frame_start;
69 static int frame_length;
70 static int frame_id;
71 static int first_bulk_packet;
72 static int frame_remaining_bytes;
73 static int frame_max_length;
75 static const uint8_t qemu_uvc_dev_descriptor[] = {
76 0x12, /* u8 bLength; */
77 0x01, /* u8 bDescriptorType; Device */
78 0x00, 0x02, /* u16 bcdUSB; v2.0 */
80 0xEF, /* u8 bDeviceClass; */
81 0x02, /* u8 bDeviceSubClass; */
82 0x01, /* u8 bDeviceProtocol; [ low/full speeds only ] */
83 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
85 /* Vendor and product id are arbitrary. */
86 0x00, 0x00, /* u16 idVendor; */
87 0x00, 0x00, /* u16 idProduct; */
88 0x00, 0x00, /* u16 bcdDevice */
90 0x01, /* u8 iManufacturer; */
91 0x02, /* u8 iProduct; */
92 0x00, /* u8 iSerialNumber; */
93 0x01 /* u8 bNumConfigurations; */
96 static const uint8_t qemu_uvc_config_descriptor[] = {
98 /* one configuration */
99 0x09, /* u8 bLength; */
100 0x02, /* u8 bDescriptorType; Configuration */
101 0xB7, 0x00, /* u16 wTotalLength; */
102 0x02, /* u8 bNumInterfaces; (2) */
103 0x01, /* u8 bConfigurationValue; */
104 0x00, /* u8 iConfiguration; */
105 0x80, /* u8 bmAttributes;
106 Bit 7: must be set,
107 6: Self-powered,
108 5: Remote wakeup,
109 4..0: resvd */
110 0xFA, /* u8 MaxPower; */
112 /* interface association */
113 0x08, /* u8 ifa_bLength; */
114 0x0B, /* u8 ifa_bDescriptorType; Interface Association */
115 0x00, /* u8 ifa_bFirstInterface; */
116 0x02, /* u8 ifa_bInterfaceCount; */
117 0x0E, /* u8 ifa_bFunctionClass; CC_VIDEO */
118 0x03, /* u8 ifa_bFunctionSubClass; SS_VIDEO_INTERFACE_COLLECTION */
119 0x00, /* u8 ifa_bFunctionProtocol; unused */
120 0x02, /* u8 ifa_iFunction; */
122 /* video control interface */
123 0x09, /* u8 if_bLength; */
124 0x04, /* u8 if_bDescriptorType; Interface */
125 0x00, /* u8 if_bInterfaceNumber; */
126 0x00, /* u8 if_bAlternateSetting; */
127 0x01, /* u8 if_bNumEndpoints; */
128 0x0E, /* u8 if_bInterfaceClass; CC_VIDEO */
129 0x01, /* u8 if_bInterfaceSubClass; SC_VIDEOCONTROL */
130 0x00, /* u8 if_bInterfaceProtocol; unused */
131 0x02, /* u8 if_iInterface; */
133 /* class specific vc interface descriptor */
134 0x0D, /* u8 cif_bLength; */
135 0x24, /* u8 cif_bDescriptorType; CS_INTERFACE */
136 0x01, /* u8 cif_bDescriptorSubType; VC_HEADER */
137 0x00, 0x01, /* u16 cif_bcdUVC; 1.0 */
138 0x42, 0x00, /* u16 cif_wTotalLength */
139 0x80, 0x8D, /* u32 cif_dwClockFrequency; Deprecated, 6Mhz */
140 0x5B, 0x00,
141 0x01, /* u8 cif_bInCollection; */
142 0x01, /* u8 cif_baInterfaceNr; */
144 /* input terminal descriptor */
145 0x11, /* u8 itd_bLength; */
146 0x24, /* u8 itd_bDescriptorType; CS_INTERFACE */
147 0x02, /* u8 itd_bDescriptorSubtype; VC_INPUT_TERMINAL */
148 0x01, /* u8 itd_bTerminalID; */
149 0x01, 0x02, /* u16 itd_wTerminalType; ITT_CAMERA */
150 0x00, /* u8 itd_bAssocTerminal; No association */
151 0x00, /* u8 itd_iTerminal; Unused */
152 0x00, 0x00, /* u16 itd_wObjectiveFocalLengthMin; No optical zoom */
153 0x00, 0x00, /* u16 itd_wObjectiveFocalLengthMax; No optical zoom */
154 0x00, 0x00, /* u16 itd_wOcularFocalLength; No optical zoom */
155 0x02, /* u8 itd_bControlSize; No controls implemented */
156 0x00, 0x00, /* u16 itd_bmControls; No controls supported */
158 0x08, /* u8 itd_bLength; */
159 0x24, /* u8 itd_bDescriptorType; CS_INTERFACE */
160 0x02, /* u8 itd_bDescriptorSubtype; VC_INPUT_TERMINAL */
161 0x02, /* u8 itd_bTerminalID; */
162 0x01, 0x04, /* u16 itd_wTerminalType; ITT_COMPOSITE */
163 0x00, /* u8 itd_bAssocTerminal; */
164 0x00, /* u8 itd_iTerminal; */
166 /* output terminal descriptor */
167 0x09, /* u8 otd_bLength; */
168 0x24, /* u8 otd_bDescriptorType; CS_INTERFACE */
169 0x03, /* u8 otd_bDescriptorSubtype; VC_OUTPUT_TERMINAL */
170 0x03, /* u8 otd_bTerminalID; */
171 0x01, 0x01, /* u16 otd_wTerminalType; TT_STREAMING */
172 0x00, /* u8 otd_bAssocTerminal; No association */
173 0x05, /* u8 otd_bSourceID; */
174 0x00, /* u8 otd_iTerminal; */
176 /* selector unit descriptor */
177 0x08, /* u8 sud_bLength; */
178 0x24, /* u8 sud_bDescriptorType; CS_INTERFACE */
179 0x04, /* u8 sud_bDescriptorSubtype; VC_SELECTOR_UNIT */
180 0x04, /* u8 sud_bUnitID; */
181 0x02, /* u8 sud_bNrInPins; */
182 0x01, /* u8 sud_baSourceID; */
183 0x02,
184 0x00, /* u8 sud_iSelector; */
186 /* processing unit descriptor */
187 0x0B, /* u8 pud_bLength; */
188 0x24, /* u8 pud_bDescriptorType; CS_INTERFACE */
189 0x05, /* u8 pud_bDescriptorSubtype; VC_PROCESSING_UNIT */
190 0x05, /* u8 pud_bUnitID; */
191 0x04, /* u8 pud_bSourceID; */
192 0x00, 0x00, /* u16 pud_wMaxMultiplier; */
193 0x02, /* u8 pud_bControlSize; */
194 0x01, 0x00, /* u16 pud_bmControls; Brightness control supported */
195 0x00, /* u8 pud_iProcessing; */
197 /* standard interrupt endpoint */
198 0x07, /* u8 ep_bLenght; */
199 0x05, /* u8 ep_bDescriptorType; Endpoint */
200 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
201 0x03, /* u8 ep_bmAttributes; Interrupt */
202 0x08, 0x00, /* u8 ep_wMaxPacketSize; 8 bytes */
203 0xFF, /* u8 ep_bInterval; 32ms */
205 /* class-specific interrupt endpoint */
206 0x05, /* u8 ep_bLenght; */
207 0x25, /* u8 ep_bDescriptorType; CS_ENDPOINT */
208 0x03, /* u8 ep_bmAttributes; EP_INTERRUPT */
209 0x08, 0x00, /* u8 ep_wMaxPacketSize; 8 bytes */
211 /* standard vs interface descriptor alternate 0 */
212 0x09, /* u8 bLength; */
213 0x04, /* u8 bDescriptorType; INTERFACE */
214 0x01, /* u8 bInterfaceNumber; */
215 0x00, /* u8 bAlternateSetting; */
216 0x01, /* u8 bNumEndpoints; */
217 0x0E, /* u8 bInterfaceClass; CC_VIDEO */
218 0x02, /* u8 bInterfaceSubClass; SC_VIDEO_STREAMING */
219 0x00, /* u8 bInterfaceProtocol; PC_PROTOCOL_UNDEFINED */
220 0x00, /* u8 iInterface; Unused */
222 /* class-specific vs header descriptor input alternate 0 */
223 0x0E, /* u8 bLength; */
224 0x24, /* u8 bDescriptorType; CS_INTERFACE */
225 0x01, /* u8 bDescriptorSubtype; VS_INPUT_HEADER */
226 0x01, /* u8 bNumFormats; */
227 0x46, 0x00, /* u8 wTotalLength; */
228 0x82, /* u8 bEndpointAddress; */
229 0x00, /* u8 bmInfo; */
230 0x03, /* u8 bTerminalLink; */
231 0x00, /* u8 bStillCaptureMethod; */
232 0x00, /* u8 bTriggerSupport; */
233 0x00, /* u8 bTriggerUsage; */
234 0x01, /* u8 bControlSize; */
235 0x00, /* u8 bmaControls; */
237 /* class-specific vs format descriptor alternate 0 */
238 0x0B, /* u8 bLength; */
239 0x24, /* u8 bDescriptorType; CS_INTERFACE */
240 0x06, /* u8 bDescriptorSubtype; VS_FORMAT_MJPEG */
241 0x01, /* u8 bFormatIndex; */
242 0x01, /* u8 bNumFrameDescriptors; */
243 0x01, /* u8 bmFlags; */
244 0x01, /* u8 bDefaultFrameIndex; */
245 0x00, /* u8 bAspectRatioX; */
246 0x00, /* u8 bAspectRatioY; */
247 0x02, /* u8 bmInterlaceFlags; */
248 0x00, /* u8 bCopyProtect; */
250 /* class-specific vs frame descriptor alternate 0 */
251 0x26, /* u8 bLength; */
252 0x24, /* u8 bDescriptorType; CS_INTERFACE */
253 0x07, /* u8 bDescriptorSubtype; VS_FRAME_MJPEG */
254 0x01, /* u8 bFrameIndex; */
255 0x01, /* u8 bmCapabilities; */
256 0x40, 0x01, /* u8 wWidth; 320 */
257 0xF0, 0x00, /* u8 wHeight; 240 */
258 0x00, 0xEC,
259 0x0D, 0x00, /* u32 dwMinBitRate; */
260 0x00, 0xEC,
261 0x0D, 0x00, /* u32 dwMaxBitRate; */
262 0x72, 0xCE,
263 0x00, 0x00, /* u32 dwMaxVideoFrameBufSize; */
264 0x2A, 0x2C,
265 0x0A, 0x00, /* u32 dwDefaultFrameInterval; */
266 0x00, /* u8 bFrameIntervalType; */
267 0x2A, 0x2C,
268 0x0A, 0x00, /* u32 dwMinFrameInterval; */
269 0x2A, 0x2C,
270 0x0A, 0x00, /* u32 dwMaxFrameInterval; */
271 0x00, 0x00,
272 0x00, 0x00, /* u32 dwFrameIntervalStep; */
274 /* standard vs isochronous video data endpoint descriptor */
275 0x07, /* u8 bLength; */
276 0x05, /* u8 bDescriptorType; */
277 0x82, /* u8 bEndpointAddress; IN endpoint 2 */
278 0x02, /* u8 bmAttributes; Isochronous transfer, asynchronous sync */
279 0x40, 0x00, /* u16 wMaxPacketSize; 510 bytes */
280 0x00 /* u8 bInterval; */
283 static void get_frame_read(void)
285 DPRINTF("Getting frame.\n");
286 frame = frame_start;
287 frame_length = read(v4l2_fd, frame, frame_max_length);
289 if(frame_length == -1)
291 DPRINTF("Error while reading frame.\n");
292 frame_length = 0;
294 else
296 frame_id = frame_id ^ 1;
297 first_bulk_packet = 1;
298 frame_remaining_bytes = frame_length;
299 DPRINTF("Got a frame of %d bytes.\n", frame_length);
302 return;
305 static void usb_uvc_handle_reset(USBDevice *dev)
307 DPRINTF("Reset called\n");
310 static int usb_uvc_handle_control(USBDevice *dev, int request, int value,
311 int index, int length, uint8_t *data)
313 int ret = 0;
314 USBUVCState *s = (USBUVCState *)dev;
316 DPRINTF("Control called\n");
317 // DPRINTF("Request: 0x%08X\n", request);
318 // DPRINTF("Value: 0x%08X\n", value);
319 // DPRINTF("Index: 0x%08X\n", index);
320 // DPRINTF("Length: 0x%08X\n", length);
322 switch(request)
324 case DeviceRequest | USB_REQ_GET_STATUS:
325 DPRINTF("USB Request: Get Status\n");
326 data[0] = (1 << USB_DEVICE_SELF_POWERED) |
327 (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
328 data[1] = 0x00;
329 ret = 2;
330 break;
331 case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
332 DPRINTF("USB Request: Clear feature\n");
333 if (value == USB_DEVICE_REMOTE_WAKEUP) {
334 DPRINTF("USB Request: Unset remote wakeup\n");
335 dev->remote_wakeup = 0;
336 } else {
337 goto fail;
339 ret = 0;
340 break;
341 case DeviceOutRequest | USB_REQ_SET_FEATURE:
342 DPRINTF("USB Request: Set feature\n");
343 if (value == USB_DEVICE_REMOTE_WAKEUP) {
344 DPRINTF("USB Request: Set remote wakeup\n");
345 dev->remote_wakeup = 1;
346 } else {
347 goto fail;
349 ret = 0;
350 break;
351 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
352 DPRINTF("USB Request: Set address to 0x%08X\n", value);
353 dev->addr = value;
354 ret = 0;
355 break;
356 case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
357 DPRINTF("USB Request: Get descriptor\n");
358 switch(value >> 8) {
359 case USB_DT_DEVICE:
360 DPRINTF("USB Request: Get device descriptor\n");
361 memcpy(data, qemu_uvc_dev_descriptor,
362 sizeof(qemu_uvc_dev_descriptor));
363 ret = sizeof(qemu_uvc_dev_descriptor);
364 break;
365 case USB_DT_CONFIG:
366 DPRINTF("USB Request: Get configuration descriptor\n");
367 memcpy(data, qemu_uvc_config_descriptor,
368 sizeof(qemu_uvc_config_descriptor));
369 ret = sizeof(qemu_uvc_config_descriptor);
370 break;
371 case USB_DT_STRING:
372 DPRINTF("USB Request: Get device strings\n");
373 switch(value & 0xff) {
374 case 0:
375 DPRINTF("USB Request: Get language IDs\n");
376 /* language ids */
377 data[0] = 4;
378 data[1] = 3;
379 data[2] = 0x09;
380 data[3] = 0x04;
381 ret = 4;
382 break;
383 case 1:
384 /* vendor description */
385 DPRINTF("USB Request: Get vendor string\n");
386 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
387 break;
388 case 2:
389 /* product description */
390 DPRINTF("USB Request: Get product string\n");
391 ret = set_usb_string(data, "QEMU USB VIDEO CLASS 2");
392 break;
393 case 3:
394 /* serial number */
395 DPRINTF("USB Request: Get serial number string\n");
396 ret = set_usb_string(data, "1");
397 break;
398 default:
399 goto fail;
401 break;
402 default:
403 goto fail;
405 break;
406 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
407 DPRINTF("USB Request: Get configuration\n");
408 data[0] = 1;
409 ret = 1;
410 break;
411 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
412 DPRINTF("USB Request: Set configuration\n");
413 ret = 0;
414 break;
415 case DeviceRequest | USB_REQ_GET_INTERFACE:
416 DPRINTF("USB Request: Get interface\n");
417 data[0] = 0;
418 ret = 1;
419 break;
420 case DeviceOutRequest | USB_REQ_SET_INTERFACE:
421 DPRINTF("USB Request: Set interface\n");
422 ret = 0;
423 break;
424 case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
425 DPRINTF("USB Request: Clear endpoint\n");
426 ret = 0;
427 break;
428 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
429 DPRINTF("USB Request: Set interface\n");
430 ret = 0;
431 break;
432 /* Class specific requests. */
433 case UVCGetVideoControl | USB_UVC_GET_CUR:
434 ret = 0;
436 if((index&0xFF) == 0x01 && ((value&0xFF00) == 0x0100 || (value&0xFF00) == 0x0200))
438 DPRINTF("USB Request: Get video control current setting attribute for interface %d\n", index&0xFF);
439 if((value&0xFF00) == 0x0100)
440 DPRINTF("\tVS_PROBE_CONTROL\n");
441 else
442 DPRINTF("\tVS_COMMIT_CONTROL\n");
444 if(length != 26)
446 DPRINTF("USB Request: Requested %d bytes, expected 26 bytes\n", length);
447 goto fail;
450 data[0] = 0; // bmHint
451 data[1] = 0;
452 data[2] = 1; // bFormatIndex
453 data[3] = 1; // bFrameIndex
454 data[4] = 0x2A; // dwFrameInterval
455 data[5] = 0x2C;
456 data[6] = 0x0A;
457 data[7] = 0x00;
458 data[8] = 0; // wKeyFrameRate
459 data[9] = 0;
460 data[10] = 0; // wPFrameRate
461 data[11] = 0;
462 data[12] = 0; // wCompQuality
463 data[13] = 0;
464 data[14] = 1; // wCompWindowSize
465 data[15] = 0;
466 data[16] = 0x20; // wDelay
467 data[17] = 0;
468 data[18] = 0x72; // dwMaxVideoFrameSize
469 data[19] = 0xCE;
470 data[20] = 0x00;
471 data[21] = 0x00;
472 data[22] = 0x72; // dwMaxPayloadTransferSize
473 data[23] = 0xCE;
474 data[24] = 0x00;
475 data[25] = 0x00;
476 ret = 26;
478 else if((index&0xFF00) == 0x0400 && (value&0xFF00) == 0x0100) // Setting input
480 DPRINTF("USB Request: Asking for current input\n");
481 if(length != 1)
483 DPRINTF("USB Request: Requested %d bytes, expected 1 byte\n", length);
484 goto fail;
487 data[0] = s->current_input;
488 ret = 1;
490 else if((index&0xFF00) == 0x0500 && (value&0xFF00) == 0x0200) // PU_BRIGHTNESS_CONTROL of PROCESSING_UNIT
492 DPRINTF("USB Resquest: Asking for current brightness\n");
493 if(length != 2)
495 DPRINTF("USB Request: Requested %d bytes, expected 2 bytes\n", length);
496 goto fail;
499 data[0] = 1;
500 data[1] = 0;
501 ret = 2;
503 else
504 goto fail;
505 break;
506 case UVCGetVideoControl | USB_UVC_GET_MIN:
507 ret = 0;
509 if((index&0xFF) == 0x01 && ((value&0xFF00) == 0x0100 || (value&0xFF00) == 0x0200))
511 DPRINTF("USB Request: Get video control minimum setting attribute for interface %d\n", index&0xFF);
513 if(length != 26)
515 DPRINTF("USB Request: Requested %d bytes, expected 26 bytes\n", length);
516 goto fail;
519 data[0] = 0; // bmHint
520 data[1] = 0;
521 data[2] = 1; // bFormatIndex
522 data[3] = 1; // bFrameIndex
523 data[4] = 0x2A; // dwFrameInterval
524 data[5] = 0x2C;
525 data[6] = 0x0A;
526 data[7] = 0x00;
527 data[8] = 0; // wKeyFrameRate
528 data[9] = 0;
529 data[10] = 0; // wPFrameRate
530 data[11] = 0;
531 data[12] = 0; // wCompQuality
532 data[13] = 0;
533 data[14] = 1; // wCompWindowSize
534 data[15] = 0;
535 data[16] = 0x20; // wDelay
536 data[17] = 0;
537 data[18] = 0x72; // dwMaxVideoFrameSize
538 data[19] = 0xCE;
539 data[20] = 0x00;
540 data[21] = 0x00;
541 data[22] = 0x72; // dwMaxPayloadTransferSize
542 data[23] = 0xCE;
543 data[24] = 0x00;
544 data[25] = 0x00;
545 ret = 26;
547 else if((index&0xFF00) == 0x0400 && (value&0xFF00) == 0x0100) // Setting input
549 DPRINTF("USB Request: Asking for minimum input\n");
550 if(length != 1)
552 DPRINTF("USB Request: Requested %d bytes, expected 1 byte\n", length);
553 goto fail;
556 data[0] = 0;
557 ret = 1;
559 else if((index&0xFF00) == 0x0500 && (value&0xFF00) == 0x0200) // PU_BRIGHTNESS_CONTROL of PROCESSING_UNIT
561 DPRINTF("USB Resquest: Asking for minimum brightness\n");
562 if(length != 2)
564 DPRINTF("USB Request: Requested %d bytes, expected 2 bytes\n", length);
565 goto fail;
568 data[0] = 1;
569 data[1] = 0;
570 ret = 2;
572 else
573 goto fail;
574 break;
575 case UVCGetVideoControl | USB_UVC_GET_MAX:
576 if((index&0xFF) == 0x01 && ((value&0xFF00) == 0x0100 || (value&0xFF00) == 0x0200))
578 DPRINTF("USB Request: Get video control maximum setting attribute for interface %d\n", index&0xFF);
580 if(length != 26)
582 DPRINTF("USB Request: Requested %d bytes, expected 26 bytes\n", length);
583 goto fail;
586 data[0] = 0; // bmHint
587 data[1] = 0;
588 data[2] = 1; // bFormatIndex
589 data[3] = 1; // bFrameIndex
590 data[4] = 0x2A; // dwFrameInterval
591 data[5] = 0x2C;
592 data[6] = 0x0A;
593 data[7] = 0x00;
594 data[8] = 0; // wKeyFrameRate
595 data[9] = 0;
596 data[10] = 0; // wPFrameRate
597 data[11] = 0;
598 data[12] = 0; // wCompQuality
599 data[13] = 0;
600 data[14] = 1; // wCompWindowSize
601 data[15] = 0;
602 data[16] = 0x20; // wDelay
603 data[17] = 0;
604 data[18] = 0x72; // dwMaxVideoFrameSize
605 data[19] = 0xCE;
606 data[20] = 0x00;
607 data[21] = 0x00;
608 data[22] = 0x72; // dwMaxPayloadTransferSize
609 data[23] = 0xCE;
610 data[24] = 0x00;
611 data[25] = 0x00;
612 ret = 26;
614 else if((index&0xFF00) == 0x0400 && (value&0xFF00) == 0x0100) // Setting input
616 DPRINTF("USB Request: Asking maximum input\n");
617 if(length != 1)
619 DPRINTF("USB Request: Requested %d bytes, expected 1 byte\n", length);
620 goto fail;
623 data[0] = 1;
624 ret = 1;
626 else if((index&0xFF00) == 0x0500 && (value&0xFF00) == 0x0200) // PU_BRIGHTNESS_CONTROL of PROCESSING_UNIT
628 DPRINTF("USB Resquest: Asking for maximum brightness\n");
629 if(length != 2)
631 DPRINTF("USB Request: Requested %d bytes, expected 2 bytes\n", length);
632 goto fail;
635 data[0] = 1;
636 data[1] = 0;
637 ret = 2;
639 else
640 goto fail;
641 break;
642 case UVCGetVideoControl | USB_UVC_GET_DEF:
643 if((index&0xFF) == 0x01 && ((value&0xFF00) == 0x0100 || (value&0xFF00) == 0x0200))
645 DPRINTF("USB Request: Get video control default setting attribute for interface %d\n", index&0xFF);
647 if(length != 26)
649 DPRINTF("USB Request: Requested %d bytes, expected 26 bytes\n", length);
650 goto fail;
653 data[0] = 0; // bmHint
654 data[1] = 0;
655 data[2] = 1; // bFormatIndex
656 data[3] = 1; // bFrameIndex
657 data[4] = 0x2A; // dwFrameInterval
658 data[5] = 0x2C;
659 data[6] = 0x0A;
660 data[7] = 0x00;
661 data[8] = 0; // wKeyFrameRate
662 data[9] = 0;
663 data[10] = 0; // wPFrameRate
664 data[11] = 0;
665 data[12] = 0; // wCompQuality
666 data[13] = 0;
667 data[14] = 1; // wCompWindowSize
668 data[15] = 0;
669 data[16] = 0x20; // wDelay
670 data[17] = 0;
671 data[18] = 0x72; // dwMaxVideoFrameSize
672 data[19] = 0xCE;
673 data[20] = 0x00;
674 data[21] = 0x00;
675 data[22] = 0x72; // dwMaxPayloadTransferSize
676 data[23] = 0xCE;
677 data[24] = 0x00;
678 data[25] = 0x00;
679 ret = 26;
681 else if((index&0xFF00) == 0x0400 && (value&0xFF00) == 0x0100) // Setting input
683 DPRINTF("USB Request: Asking for default input\n");
684 if(length != 1)
686 DPRINTF("USB Request: Requested %d bytes, expected 1 byte\n", length);
687 goto fail;
690 data[0] = 0;
691 ret = 1;
693 else if((index&0xFF00) == 0x0500 && (value&0xFF00) == 0x0200) // PU_BRIGHTNESS_CONTROL of PROCESSING_UNIT
695 DPRINTF("USB Resquest: Asking for default brightness\n");
696 if(length != 2)
698 DPRINTF("USB Request: Requested %d bytes, expected 2 bytes\n", length);
699 goto fail;
702 data[0] = 1;
703 data[1] = 0;
704 ret = 2;
706 else
707 goto fail;
708 break;
709 case UVCSetVideoControl | USB_UVC_SET_CUR:
710 DPRINTF("USB Request: Set video control setting attribute for interface %d\n", index&0xFF);
712 ret = 0;
714 if((index&0xFF) == 0x01 && ((value&0xFF00) == 0x0100 || (value&0xFF00) == 0x0200))
716 if((value&0xFF00) == 0x0100)
717 DPRINTF("\tVS_PROBE_CONTROL\n");
718 else
719 DPRINTF("\tVS_COMMIT_CONTROL\n");
721 if(length != 26)
723 DPRINTF("USB Request: Requested %d bytes, expected 26 bytes\n", length);
724 goto fail;
727 DPRINTF("\tbmHint = 0x%02X%02X\n", data[1], data[0]);
728 DPRINTF("\tbFormatIndex = %d\n", data[2]);
729 DPRINTF("\tbFrameIndex = %d\n", data[3]);
730 DPRINTF("\tdwFrameInterval = 0x%02X%02X%02X%02X\n", data[7], data[6], data[5], data[4]);
731 DPRINTF("\twKeyFrameRate = 0x%02X%02X\n", data[9], data[8]);
732 DPRINTF("\twPFrameRate = 0x%02X%02X\n", data[11], data[10]);
733 DPRINTF("\twCompQuality = 0x%02X%02X\n", data[13], data[12]);
734 DPRINTF("\twCompWindowSize = 0x%02X%02X\n", data[15], data[14]);
735 DPRINTF("\twDelay = 0x%02X%02X\n", data[17], data[16]);
736 DPRINTF("\tdwMaxVideoFrameSize= 0x%02X%02X%02X%02X\n", data[21], data[20], data[19], data[18]);
737 DPRINTF("\tdwMaxPayloadTransferSize= 0x%02X%02X%02X%02X\n", data[25], data[24], data[23], data[22]);
739 frame = frame_start;
740 frame_remaining_bytes = frame_length;
741 first_bulk_packet = 1;
743 ret = 26;
745 else if((index&0xFF00) == 0x0400 && (value&0xFF00) == 0x0100) // Setting input
747 DPRINTF("Setting input to %d\n", data[0]);
748 if(length != 1)
750 DPRINTF("USB Request: Requested %d bytes, expected 1 byte\n", length);
751 goto fail;
754 s->current_input = data[0];
755 ret = 1;
757 else if((index&0xFF00) == 0x0500 && (value&0xFF00) == 0x0200) // PU_BRIGHTNESS_CONTROL of PROCESSING_UNIT
759 DPRINTF("USB Resquest: Setting brightness, value stays the same\n");
760 if(length != 2)
762 DPRINTF("USB Request: Requested %d bytes, expected 2 bytes\n", length);
763 goto fail;
766 ret = 2;
768 else
769 goto fail;
770 break;
771 case UVCGetVideoControl | USB_UVC_GET_RES:
772 if((index&0xFF00) == 0x0500 && (value&0xFF00) == 0x0200) // PU_BRIGHTNESS_CONTROL of PROCESSING_UNIT
774 DPRINTF("USB Resquest: Asking for brightness resolution\n");
775 if(length != 2)
777 DPRINTF("USB Request: Requested %d bytes, expected 2 bytes\n", length);
778 goto fail;
781 data[0] = 1;
782 data[1] = 0;
783 ret = 2;
785 else
786 goto fail;
787 break;
788 default:
789 fail:
790 DPRINTF("USB Request: Unhandled control request\n");
791 DPRINTF("\tRequest: 0x%08X\n", request);
792 DPRINTF("\tValue: 0x%08X\n", value);
793 DPRINTF("\tIndex: 0x%08X\n", index);
794 DPRINTF("\tLength: 0x%08X\n", length);
795 ret = USB_RET_STALL;
796 break;
799 return ret;
802 static int usb_uvc_handle_data(USBDevice *dev, USBPacket *p)
804 int ret = 0;
806 //DPRINTF("Data called\n");
807 //DPRINTF("Packet ID: %d\n", p->pid);
808 //DPRINTF("Device address: %d\n", p->devaddr);
809 //DPRINTF("Device endpoint: %d\n", p->devep);
810 //DPRINTF("Data length: %d\n", p->len);
812 switch (p->pid)
814 case USB_TOKEN_OUT:
815 DPRINTF("USB Data Out requested.\n");
816 break;
817 case USB_TOKEN_IN:
818 if(p->devep == 1) // IN endpoint 1 (hardware button)
820 p->data[0] = 2;
821 p->data[1] = 1;
822 p->data[2] = 0;
823 p->data[3] = 0;
825 else if(p->devep == 2) // IN endpoint 2 (video data)
827 if(first_bulk_packet)
829 p->data[0] = 2;
830 p->data[1] = 0x82 | frame_id;
831 memcpy((p->data)+2,frame,62);
832 ret = 64;
833 first_bulk_packet=0;
834 frame = frame + 62;
835 frame_remaining_bytes = frame_remaining_bytes - 62;
837 else if(frame_remaining_bytes<64)
839 memcpy(p->data,frame,frame_remaining_bytes);
840 ret = frame_remaining_bytes;
841 get_frame_read();
843 else if(frame_remaining_bytes==64)
845 memcpy(p->data,frame,frame_remaining_bytes);
846 ret = frame_remaining_bytes;
847 frame_remaining_bytes = 0;
849 else if(frame_remaining_bytes==0)
851 ret = 0;
852 get_frame_read();
854 else
856 memcpy(p->data,frame,64);
857 frame = frame+64;
858 frame_remaining_bytes = frame_remaining_bytes-64;
859 ret = 64;
862 else
864 DPRINTF("USB Data In requested.\n");
865 DPRINTF("Requested data from endpoint %02X\n", p->devep);
867 break;
868 default:
869 DPRINTF("Bad token: %d\n", p->pid);
870 //fail:
871 ret = USB_RET_STALL;
872 break;
875 return ret;
878 static void usb_uvc_handle_destroy(USBDevice *dev)
880 DPRINTF("Destroy called\n");
881 close(v4l2_fd);
884 static int usb_uvc_initfn(USBDevice *dev)
886 struct v4l2_capability capabilities;
887 struct v4l2_input video_input;
888 struct v4l2_format v_format;
889 int video_input_index;
890 int ret_err;
892 DPRINTF("Init called\n");
894 USBUVCState *s = (USBUVCState *)dev;
896 s->current_input = 0;
897 s->dev.speed = USB_SPEED_FULL;
899 if (!s->v4l2_device) {
900 error_report("V4L2 device specification needed.\n");
901 return -1;
903 else
905 DPRINTF("Trying to open %s\n.", s->v4l2_device);
908 v4l2_fd = open(s->v4l2_device, O_RDWR);
910 if(v4l2_fd==-1)
912 switch(errno)
914 case EACCES:
915 error_report("Access denied.");
916 break;
917 case EBUSY:
918 error_report("Device busy.");
919 break;
920 case ENXIO:
921 error_report("Device does not exist.");
922 break;
923 case ENOMEM:
924 error_report("Not enough memory to open device.");
925 break;
926 case EMFILE:
927 error_report("Process reached maximum files opened.");
928 break;
929 case ENFILE:
930 error_report("System reached maximum files opened.");
931 break;
932 default:
933 error_report("Unknown error %d opening device.", errno);
934 break;
937 return -1;
940 DPRINTF("Device opened correctly.\n");
942 DPRINTF("Querying capabilities.\n");
944 ret_err = ioctl(v4l2_fd, VIDIOC_QUERYCAP, &capabilities);
946 if(ret_err==-1)
948 switch(errno)
950 case EINVAL:
951 error_report("Device is not V4L2 device.\n");
952 break;
953 default:
954 error_report("Device returned unknown error %d.\n", errno);
955 break;
958 return -1;
961 DPRINTF("Device driver: %s\n", capabilities.driver);
962 DPRINTF("Device name: %s\n", capabilities.card);
963 DPRINTF("Device bus: %s\n", capabilities.bus_info);
964 DPRINTF("Driver version: %u.%u.%u\n",(capabilities.version >> 16) & 0xFF,(capabilities.version >> 8) & 0xFF, capabilities.version & 0xFF);
965 DPRINTF("Device capabilities: 0x%08X\n", capabilities.capabilities);
967 DPRINTF("Enumerating video inputs.\n");
968 memset(&video_input, 0, sizeof(video_input));
969 video_input.index=0;
970 while((ioctl(v4l2_fd, VIDIOC_ENUMINPUT, &video_input)==0))
972 if(video_input.type == V4L2_INPUT_TYPE_CAMERA)
974 video_input_index = video_input.index;
975 break;
978 video_input.index++;
981 DPRINTF("Setting video input to index %d\n", video_input_index);
982 ret_err = ioctl(v4l2_fd, VIDIOC_S_INPUT, &video_input_index);
984 if(ret_err==-1)
986 switch(errno)
988 case EINVAL:
989 error_report("Incorrect video input selected.\n");
990 break;
991 case EBUSY:
992 error_report("Input cannot be switched.\n");
993 break;
994 default:
995 error_report("Unknown error %d.\n", errno);
996 break;
999 return -1;
1002 ioctl(v4l2_fd, VIDIOC_G_INPUT, &ret_err);
1004 if(ret_err==video_input_index)
1005 DPRINTF("Video input correctly set.\n");
1006 else
1008 error_report("Some error happened while setting video input.\n");
1009 return -1;
1012 DPRINTF("Trying to set 320x240 MJPEG.\n");
1013 memset(&v_format, 0, sizeof(v_format));
1014 v_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1015 v_format.fmt.pix.width = 320;
1016 v_format.fmt.pix.height = 240;
1017 v_format.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
1018 v_format.fmt.pix.field = V4L2_FIELD_INTERLACED;
1020 ret_err = ioctl (v4l2_fd, VIDIOC_S_FMT, &v_format);
1022 if(ret_err == -1)
1024 switch(errno)
1026 case EBUSY:
1027 error_report("Device busy while changing format.\n");
1028 break;
1029 case EINVAL:
1030 error_report("Invalid format.\n");
1031 break;
1032 default:
1033 error_report("Unknown error %d while changing format.\n", errno);
1034 break;
1037 return -1;
1040 frame_max_length = v_format.fmt.pix.sizeimage;
1042 DPRINTF("Format correctly set.\n");
1043 DPRINTF("Maximum image size: %d bytes.\n", frame_max_length);
1045 DPRINTF("Allocating memory for frames.\n");
1046 frame = malloc(frame_max_length);
1047 frame_start = frame;
1049 frame_id = 1;
1051 get_frame_read();
1053 return 0;
1056 static USBDevice *usb_uvc_init(const char *filename)
1058 USBDevice *dev;
1060 dev = usb_create(NULL /* FIXME */, "usb-uvc-webcam");
1061 qdev_init_nofail(&dev->qdev);
1063 DPRINTF("Filename: %s\n.", filename);
1065 if (!*filename) {
1066 error_report("character device specification needed");
1067 return NULL;
1070 return dev;
1073 static struct USBDeviceInfo usb_uvc_info = {
1074 .product_desc = "QEMU USB Video Class Device",
1075 .qdev.name = "usb-uvc-webcam",
1076 .qdev.desc = "QEMU USB Video Class Device",
1077 .usbdevice_name = "uvc-webcam",
1078 .usbdevice_init = usb_uvc_init,
1079 .qdev.size = sizeof(USBUVCState),
1080 .init = usb_uvc_initfn,
1081 .handle_packet = usb_generic_handle_packet,
1082 .handle_reset = usb_uvc_handle_reset,
1083 .handle_control = usb_uvc_handle_control,
1084 .handle_data = usb_uvc_handle_data,
1085 .handle_destroy = usb_uvc_handle_destroy,
1086 .qdev.props = (Property[]) {
1087 DEFINE_PROP_STRING("device", USBUVCState, v4l2_device),
1088 DEFINE_PROP_END_OF_LIST(),
1092 static void usb_uvc_register_devices(void)
1094 usb_qdev_register(&usb_uvc_info);
1096 device_init(usb_uvc_register_devices)