1 /*********************************************************************
2 * Software License Agreement (BSD License)
4 * Copyright (C) 2010-2012 Ken Tossell
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the author nor other contributors may be
18 * used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
35 * @defgroup device Device handling and enumeration
38 #include "libuvc/libuvc.h"
39 #include "libuvc/libuvc_internal.h"
41 int uvc_already_open(uvc_context_t *ctx, struct libusb_device *usb_dev);
42 void uvc_free_devh(uvc_device_handle_t *devh);
44 uvc_error_t uvc_get_device_info(uvc_device_t *dev, uvc_device_info_t **info);
45 void uvc_free_device_info(uvc_device_info_t *info);
47 uvc_error_t uvc_scan_control(uvc_device_t *dev, uvc_device_info_t *info);
48 uvc_error_t uvc_parse_vc(uvc_device_t *dev,
49 uvc_device_info_t *info,
50 const unsigned char *block, size_t block_size);
51 uvc_error_t uvc_parse_vc_extension_unit(uvc_device_t *dev,
52 uvc_device_info_t *info,
53 const unsigned char *block,
55 uvc_error_t uvc_parse_vc_header(uvc_device_t *dev,
56 uvc_device_info_t *info,
57 const unsigned char *block, size_t block_size);
58 uvc_error_t uvc_parse_vc_input_terminal(uvc_device_t *dev,
59 uvc_device_info_t *info,
60 const unsigned char *block,
62 uvc_error_t uvc_parse_vc_processing_unit(uvc_device_t *dev,
63 uvc_device_info_t *info,
64 const unsigned char *block,
67 uvc_error_t uvc_scan_streaming(uvc_device_t *dev,
68 uvc_device_info_t *info,
70 uvc_error_t uvc_parse_vs(uvc_device_t *dev,
71 uvc_device_info_t *info,
72 uvc_streaming_interface_t *stream_if,
73 const unsigned char *block, size_t block_size);
74 uvc_error_t uvc_parse_vs_format_uncompressed(uvc_streaming_interface_t *stream_if,
75 const unsigned char *block,
77 uvc_error_t uvc_parse_vs_format_mjpeg(uvc_streaming_interface_t *stream_if,
78 const unsigned char *block,
80 uvc_error_t uvc_parse_vs_frame_uncompressed(uvc_streaming_interface_t *stream_if,
81 const unsigned char *block,
83 uvc_error_t uvc_parse_vs_input_header(uvc_streaming_interface_t *stream_if,
84 const unsigned char *block,
87 void _uvc_status_callback(struct libusb_transfer *transfer);
90 * @brief Test whether the specified USB device has been opened as a UVC device
93 * @param ctx Context in which to search for the UVC device
94 * @param usb_dev USB device to find
95 * @return true if the device is open in this context
97 int uvc_already_open(uvc_context_t *ctx, struct libusb_device *usb_dev) {
98 uvc_device_handle_t *devh;
100 DL_FOREACH(ctx->open_devices, devh) {
101 if (usb_dev == devh->dev->usb_dev)
108 /** @brief Finds a camera identified by vendor, product and/or serial number
111 * @param[in] ctx UVC context in which to search for the camera
112 * @param[out] dev Reference to the camera, or NULL if not found
113 * @param[in] vid Vendor ID number, optional
114 * @param[in] pid Product ID number, optional
115 * @param[in] sn Serial number or NULL
116 * @return Error finding device or UVC_SUCCESS
118 uvc_error_t uvc_find_device(
119 uvc_context_t *ctx, uvc_device_t **dev,
120 int vid, int pid, const char *sn) {
121 uvc_error_t ret = UVC_SUCCESS;
124 uvc_device_t *test_dev;
130 ret = uvc_get_device_list(ctx, &list);
132 if (ret != UVC_SUCCESS) {
140 while (!found_dev && (test_dev = list[dev_idx++]) != NULL) {
141 uvc_device_descriptor_t *desc;
143 if (uvc_get_device_descriptor(test_dev, &desc) != UVC_SUCCESS)
146 if ((!vid || desc->idVendor == vid)
147 && (!pid || desc->idProduct == pid)
148 && (!sn || (desc->serialNumber && !strcmp(desc->serialNumber, sn))))
151 uvc_free_device_descriptor(desc);
155 uvc_ref_device(test_dev);
157 uvc_free_device_list(list, 1);
161 UVC_EXIT(UVC_SUCCESS);
164 UVC_EXIT(UVC_ERROR_NO_DEVICE);
165 return UVC_ERROR_NO_DEVICE;
169 /** @brief Get the number of the bus to which the device is attached
172 uint8_t uvc_get_bus_number(uvc_device_t *dev) {
173 return libusb_get_bus_number(dev->usb_dev);
176 /** @brief Get the number assigned to the device within its bus
179 uint8_t uvc_get_device_address(uvc_device_t *dev) {
180 return libusb_get_device_address(dev->usb_dev);
183 /** @brief Open a UVC device
186 * @param dev Device to open
187 * @param[out] devh Handle on opened device
188 * @return Error opening device or SUCCESS
190 uvc_error_t uvc_open(
192 uvc_device_handle_t **devh) {
194 struct libusb_device_handle *usb_devh;
195 uvc_device_handle_t *internal_devh;
196 struct libusb_device_descriptor desc;
200 ret = libusb_open(dev->usb_dev, &usb_devh);
201 UVC_DEBUG("libusb_open() = %d", ret);
203 if (ret != UVC_SUCCESS) {
210 internal_devh = calloc(1, sizeof(*internal_devh));
211 internal_devh->dev = dev;
212 internal_devh->usb_devh = usb_devh;
214 ret = uvc_get_device_info(dev, &(internal_devh->info));
216 if (ret != UVC_SUCCESS)
219 /* Automatically attach/detach kernel driver on supported platforms */
220 libusb_set_auto_detach_kernel_driver(usb_devh, 1);
222 UVC_DEBUG("claiming control interface %d", internal_devh->info->ctrl_if.bInterfaceNumber);
223 ret = uvc_claim_if(internal_devh, internal_devh->info->ctrl_if.bInterfaceNumber);
224 if (ret != UVC_SUCCESS)
227 libusb_get_device_descriptor(dev->usb_dev, &desc);
228 internal_devh->is_isight = (desc.idVendor == 0x05ac && desc.idProduct == 0x8501);
230 if (internal_devh->info->ctrl_if.bEndpointAddress) {
231 internal_devh->status_xfer = libusb_alloc_transfer(0);
232 if (!internal_devh->status_xfer) {
233 ret = UVC_ERROR_NO_MEM;
237 libusb_fill_interrupt_transfer(internal_devh->status_xfer,
239 internal_devh->info->ctrl_if.bEndpointAddress,
240 internal_devh->status_buf,
241 sizeof(internal_devh->status_buf),
242 _uvc_status_callback,
245 ret = libusb_submit_transfer(internal_devh->status_xfer);
246 UVC_DEBUG("libusb_submit_transfer() = %d", ret);
250 "uvc: device has a status interrupt endpoint, but unable to read from it\n");
255 if (dev->ctx->own_usb_ctx && dev->ctx->open_devices == NULL) {
256 /* Since this is our first device, we need to spawn the event handler thread */
257 uvc_start_handler_thread(dev->ctx);
260 DL_APPEND(dev->ctx->open_devices, internal_devh);
261 *devh = internal_devh;
268 uvc_release_if(internal_devh, internal_devh->info->ctrl_if.bInterfaceNumber);
269 libusb_close(usb_devh);
270 uvc_unref_device(dev);
271 uvc_free_devh(internal_devh);
280 * @brief Parses the complete device descriptor for a device
282 * @note Free *info with uvc_free_device_info when you're done
284 * @param dev Device to parse descriptor for
285 * @param info Where to store a pointer to the new info struct
287 uvc_error_t uvc_get_device_info(uvc_device_t *dev,
288 uvc_device_info_t **info) {
290 uvc_device_info_t *internal_info;
294 internal_info = calloc(1, sizeof(*internal_info));
295 if (!internal_info) {
296 UVC_EXIT(UVC_ERROR_NO_MEM);
297 return UVC_ERROR_NO_MEM;
300 if (libusb_get_config_descriptor(dev->usb_dev,
302 &(internal_info->config)) != 0) {
304 UVC_EXIT(UVC_ERROR_IO);
308 ret = uvc_scan_control(dev, internal_info);
309 if (ret != UVC_SUCCESS) {
310 uvc_free_device_info(internal_info);
315 *info = internal_info;
323 * @brief Frees the device descriptor for a device
326 * @param info Which device info block to free
328 void uvc_free_device_info(uvc_device_info_t *info) {
329 uvc_input_terminal_t *input_term, *input_term_tmp;
330 uvc_processing_unit_t *proc_unit, *proc_unit_tmp;
331 uvc_extension_unit_t *ext_unit, *ext_unit_tmp;
333 uvc_streaming_interface_t *stream_if, *stream_if_tmp;
334 uvc_format_desc_t *format, *format_tmp;
335 uvc_frame_desc_t *frame, *frame_tmp;
339 DL_FOREACH_SAFE(info->ctrl_if.input_term_descs, input_term, input_term_tmp) {
340 DL_DELETE(info->ctrl_if.input_term_descs, input_term);
344 DL_FOREACH_SAFE(info->ctrl_if.processing_unit_descs, proc_unit, proc_unit_tmp) {
345 DL_DELETE(info->ctrl_if.processing_unit_descs, proc_unit);
349 DL_FOREACH_SAFE(info->ctrl_if.extension_unit_descs, ext_unit, ext_unit_tmp) {
350 DL_DELETE(info->ctrl_if.extension_unit_descs, ext_unit);
354 DL_FOREACH_SAFE(info->stream_ifs, stream_if, stream_if_tmp) {
355 DL_FOREACH_SAFE(stream_if->format_descs, format, format_tmp) {
356 DL_FOREACH_SAFE(format->frame_descs, frame, frame_tmp) {
357 if (frame->intervals)
358 free(frame->intervals);
360 DL_DELETE(format->frame_descs, frame);
364 DL_DELETE(stream_if->format_descs, format);
368 DL_DELETE(info->stream_ifs, stream_if);
373 libusb_free_config_descriptor(info->config);
381 * @brief Get a descriptor that contains the general information about
385 * Free *desc with uvc_free_device_descriptor when you're done.
387 * @param dev Device to fetch information about
388 * @param[out] desc Descriptor structure
389 * @return Error if unable to fetch information, else SUCCESS
391 uvc_error_t uvc_get_device_descriptor(
393 uvc_device_descriptor_t **desc) {
394 uvc_device_descriptor_t *desc_internal;
395 struct libusb_device_descriptor usb_desc;
396 struct libusb_device_handle *usb_devh;
401 ret = libusb_get_device_descriptor(dev->usb_dev, &usb_desc);
403 if (ret != UVC_SUCCESS) {
408 desc_internal = calloc(1, sizeof(*desc_internal));
409 desc_internal->idVendor = usb_desc.idVendor;
410 desc_internal->idProduct = usb_desc.idProduct;
412 if (libusb_open(dev->usb_dev, &usb_devh) == 0) {
413 unsigned char serial_buf[64];
415 int serial_bytes = libusb_get_string_descriptor_ascii(
416 usb_devh, usb_desc.iSerialNumber, serial_buf, sizeof(serial_buf));
418 if (serial_bytes > 0)
419 desc_internal->serialNumber = strdup((const char*) serial_buf);
421 /** @todo get manufacturer, product names */
423 libusb_close(usb_devh);
425 UVC_DEBUG("can't open device %04x:%04x, not fetching serial",
426 usb_desc.idVendor, usb_desc.idProduct);
429 *desc = desc_internal;
436 * @brief Frees a device descriptor created with uvc_get_device_descriptor
439 * @param desc Descriptor to free
441 void uvc_free_device_descriptor(
442 uvc_device_descriptor_t *desc) {
445 if (desc->serialNumber)
446 free((void*) desc->serialNumber);
448 if (desc->manufacturer)
449 free((void*) desc->manufacturer);
452 free((void*) desc->product);
460 * @brief Get a list of the UVC devices attached to the system
463 * @note Free the list with uvc_free_device_list when you're done.
465 * @param ctx UVC context in which to list devices
466 * @param list List of uvc_device structures
467 * @return Error if unable to list devices, else SUCCESS
469 uvc_error_t uvc_get_device_list(
471 uvc_device_t ***list) {
473 struct libusb_device **usb_dev_list;
474 struct libusb_device *usb_dev;
477 uvc_device_t **list_internal;
482 struct libusb_device_handle *usb_devh;
483 struct libusb_config_descriptor *config;
484 uint8_t got_interface;
488 const struct libusb_interface *interface;
492 const struct libusb_interface_descriptor *if_desc;
496 num_usb_devices = libusb_get_device_list(ctx->usb_ctx, &usb_dev_list);
498 if (num_usb_devices < 0) {
499 UVC_EXIT(UVC_ERROR_IO);
503 list_internal = malloc(sizeof(*list_internal));
504 *list_internal = NULL;
509 while ((usb_dev = usb_dev_list[++dev_idx]) != NULL) {
513 if (libusb_get_config_descriptor(usb_dev, 0, &config) != 0)
516 for (interface_idx = 0;
517 !got_interface && interface_idx < config->bNumInterfaces;
519 interface = &config->interface[interface_idx];
521 for (altsetting_idx = 0;
522 !got_interface && altsetting_idx < interface->num_altsetting;
524 if_desc = &interface->altsetting[altsetting_idx];
526 /* Video, Streaming */
527 if (if_desc->bInterfaceClass == 14 && if_desc->bInterfaceSubClass == 2) {
533 libusb_free_config_descriptor(config);
536 uvc_device_t *uvc_dev = malloc(sizeof(*uvc_dev));
539 uvc_dev->usb_dev = usb_dev;
540 uvc_ref_device(uvc_dev);
543 list_internal = realloc(list_internal, (num_uvc_devices + 1) * sizeof(*list_internal));
545 list_internal[num_uvc_devices - 1] = uvc_dev;
546 list_internal[num_uvc_devices] = NULL;
548 UVC_DEBUG(" UVC: %d", dev_idx);
550 UVC_DEBUG("non-UVC: %d", dev_idx);
554 libusb_free_device_list(usb_dev_list, 1);
556 *list = list_internal;
558 UVC_EXIT(UVC_SUCCESS);
563 * @brief Frees a list of device structures created with uvc_get_device_list.
566 * @param list Device list to free
567 * @param unref_devices Decrement the reference counter for each device
568 * in the list, and destroy any entries that end up with zero references
570 void uvc_free_device_list(uvc_device_t **list, uint8_t unref_devices) {
577 while ((dev = list[dev_idx++]) != NULL) {
578 uvc_unref_device(dev);
588 * @brief Get the uvc_device_t corresponding to an open device
591 * @note Unref the uvc_device_t when you're done with it
593 * @param devh Device handle to an open UVC device
595 uvc_device_t *uvc_get_device(uvc_device_handle_t *devh) {
596 uvc_ref_device(devh->dev);
601 * @brief Get the underlying libusb device handle for an open device
604 * This can be used to access other interfaces on the same device, e.g.
605 * a webcam microphone.
607 * @note The libusb device handle is only valid while the UVC device is open;
608 * it will be invalidated upon calling uvc_close.
610 * @param devh UVC device handle to an open device
612 libusb_device_handle *uvc_get_libusb_handle(uvc_device_handle_t *devh) {
613 return devh->usb_devh;
617 * @brief Get input terminal descriptors for the open device.
619 * @note Do not modify the returned structure.
620 * @note The returned structure is part of a linked list. Iterate through
621 * it by using the 'next' pointers.
623 * @param devh Device handle to an open UVC device
625 const uvc_input_terminal_t *uvc_get_input_terminals(uvc_device_handle_t *devh) {
626 return devh->info->ctrl_if.input_term_descs;
630 * @brief Get output terminal descriptors for the open device.
632 * @note Do not modify the returned structure.
633 * @note The returned structure is part of a linked list. Iterate through
634 * it by using the 'next' pointers.
636 * @param devh Device handle to an open UVC device
638 const uvc_output_terminal_t *uvc_get_output_terminals(uvc_device_handle_t *devh) {
639 return NULL; /* @todo */
643 * @brief Get processing unit descriptors for the open device.
645 * @note Do not modify the returned structure.
646 * @note The returned structure is part of a linked list. Iterate through
647 * it by using the 'next' pointers.
649 * @param devh Device handle to an open UVC device
651 const uvc_processing_unit_t *uvc_get_processing_units(uvc_device_handle_t *devh) {
652 return devh->info->ctrl_if.processing_unit_descs;
656 * @brief Get extension unit descriptors for the open device.
658 * @note Do not modify the returned structure.
659 * @note The returned structure is part of a linked list. Iterate through
660 * it by using the 'next' pointers.
662 * @param devh Device handle to an open UVC device
664 const uvc_extension_unit_t *uvc_get_extension_units(uvc_device_handle_t *devh) {
665 return devh->info->ctrl_if.extension_unit_descs;
669 * @brief Increment the reference count for a device
672 * @param dev Device to reference
674 void uvc_ref_device(uvc_device_t *dev) {
678 libusb_ref_device(dev->usb_dev);
684 * @brief Decrement the reference count for a device
686 * @note If the count reaches zero, the device will be discarded
688 * @param dev Device to unreference
690 void uvc_unref_device(uvc_device_t *dev) {
693 libusb_unref_device(dev->usb_dev);
703 * Claim a UVC interface, detaching the kernel driver if necessary.
706 * @param devh UVC device handle
707 * @param idx UVC interface index
709 uvc_error_t uvc_claim_if(uvc_device_handle_t *devh, int idx) {
714 UVC_DEBUG("claiming interface %d", idx);
715 ret = libusb_claim_interface(devh->usb_devh, idx);
722 * Release a UVC interface.
725 * @param devh UVC device handle
726 * @param idx UVC interface index
728 uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx) {
732 UVC_DEBUG("releasing interface %d", idx);
733 /* libusb_release_interface *should* reset the alternate setting to the first available,
734 but sometimes (e.g. on Darwin) it doesn't. Thus, we do it explicitly here.
735 This is needed to de-initialize certain cameras. */
736 libusb_set_interface_alt_setting(devh->usb_devh, idx, 0);
737 ret = libusb_release_interface(devh->usb_devh, idx);
744 * Find a device's VideoControl interface and process its descriptor
747 uvc_error_t uvc_scan_control(uvc_device_t *dev, uvc_device_info_t *info) {
748 const struct libusb_interface_descriptor *if_desc;
749 uvc_error_t parse_ret, ret;
751 const unsigned char *buffer;
752 size_t buffer_left, block_size;
759 for (interface_idx = 0; interface_idx < info->config->bNumInterfaces; ++interface_idx) {
760 if_desc = &info->config->interface[interface_idx].altsetting[0];
762 if (if_desc->bInterfaceClass == 14 && if_desc->bInterfaceSubClass == 1) // Video, Control
768 if (if_desc == NULL) {
769 UVC_EXIT(UVC_ERROR_INVALID_DEVICE);
770 return UVC_ERROR_INVALID_DEVICE;
773 info->ctrl_if.bInterfaceNumber = interface_idx;
774 if (if_desc->bNumEndpoints != 0) {
775 info->ctrl_if.bEndpointAddress = if_desc->endpoint[0].bEndpointAddress;
778 buffer = if_desc->extra;
779 buffer_left = if_desc->extra_length;
781 while (buffer_left >= 3) { // parseX needs to see buf[0,2] = length,type
782 block_size = buffer[0];
783 parse_ret = uvc_parse_vc(dev, info, buffer, block_size);
785 if (parse_ret != UVC_SUCCESS) {
790 buffer_left -= block_size;
791 buffer += block_size;
799 * @brief Parse a VideoControl header.
802 uvc_error_t uvc_parse_vc_header(uvc_device_t *dev,
803 uvc_device_info_t *info,
804 const unsigned char *block, size_t block_size) {
806 uvc_error_t scan_ret, ret = UVC_SUCCESS;
812 uvc_version = (block[4] >> 4) * 1000 + (block[4] & 0x0f) * 100
813 + (block[3] >> 4) * 10 + (block[3] & 0x0f);
816 info->ctrl_if.bcdUVC = SW_TO_SHORT(&block[3]);
818 switch (info->ctrl_if.bcdUVC) {
824 UVC_EXIT(UVC_ERROR_NOT_SUPPORTED);
825 return UVC_ERROR_NOT_SUPPORTED;
828 for (i = 12; i < block_size; ++i) {
829 scan_ret = uvc_scan_streaming(dev, info, block[i]);
830 if (scan_ret != UVC_SUCCESS) {
841 * @brief Parse a VideoControl input terminal.
844 uvc_error_t uvc_parse_vc_input_terminal(uvc_device_t *dev,
845 uvc_device_info_t *info,
846 const unsigned char *block, size_t block_size) {
847 uvc_input_terminal_t *term;
852 /* only supporting camera-type input terminals */
853 if (SW_TO_SHORT(&block[4]) != UVC_ITT_CAMERA) {
854 UVC_EXIT(UVC_SUCCESS);
858 term = calloc(1, sizeof(*term));
860 term->bTerminalID = block[3];
861 term->wTerminalType = SW_TO_SHORT(&block[4]);
862 term->wObjectiveFocalLengthMin = SW_TO_SHORT(&block[8]);
863 term->wObjectiveFocalLengthMax = SW_TO_SHORT(&block[10]);
864 term->wOcularFocalLength = SW_TO_SHORT(&block[12]);
866 for (i = 14 + block[14]; i >= 15; --i)
867 term->bmControls = block[i] + (term->bmControls << 8);
869 DL_APPEND(info->ctrl_if.input_term_descs, term);
871 UVC_EXIT(UVC_SUCCESS);
876 * @brief Parse a VideoControl processing unit.
879 uvc_error_t uvc_parse_vc_processing_unit(uvc_device_t *dev,
880 uvc_device_info_t *info,
881 const unsigned char *block, size_t block_size) {
882 uvc_processing_unit_t *unit;
887 unit = calloc(1, sizeof(*unit));
888 unit->bUnitID = block[3];
889 unit->bSourceID = block[4];
891 for (i = 7 + block[7]; i >= 8; --i)
892 unit->bmControls = block[i] + (unit->bmControls << 8);
894 DL_APPEND(info->ctrl_if.processing_unit_descs, unit);
896 UVC_EXIT(UVC_SUCCESS);
901 * @brief Parse a VideoControl extension unit.
904 uvc_error_t uvc_parse_vc_extension_unit(uvc_device_t *dev,
905 uvc_device_info_t *info,
906 const unsigned char *block, size_t block_size) {
907 uvc_extension_unit_t *unit = calloc(1, sizeof(*unit));
908 const uint8_t *start_of_controls;
909 int size_of_controls, num_in_pins;
914 unit->bUnitID = block[3];
915 memcpy(unit->guidExtensionCode, &block[4], 16);
917 num_in_pins = block[21];
918 size_of_controls = block[22 + num_in_pins];
919 start_of_controls = &block[23 + num_in_pins];
921 for (i = size_of_controls - 1; i >= 0; --i)
922 unit->bmControls = start_of_controls[i] + (unit->bmControls << 8);
924 DL_APPEND(info->ctrl_if.extension_unit_descs, unit);
926 UVC_EXIT(UVC_SUCCESS);
931 * Process a single VideoControl descriptor block
934 uvc_error_t uvc_parse_vc(
936 uvc_device_info_t *info,
937 const unsigned char *block, size_t block_size) {
938 int descriptor_subtype;
939 uvc_error_t ret = UVC_SUCCESS;
943 if (block[1] != 36) { // not a CS_INTERFACE descriptor??
944 UVC_EXIT(UVC_SUCCESS);
945 return UVC_SUCCESS; // UVC_ERROR_INVALID_DEVICE;
948 descriptor_subtype = block[2];
950 switch (descriptor_subtype) {
952 ret = uvc_parse_vc_header(dev, info, block, block_size);
954 case UVC_VC_INPUT_TERMINAL:
955 ret = uvc_parse_vc_input_terminal(dev, info, block, block_size);
957 case UVC_VC_OUTPUT_TERMINAL:
959 case UVC_VC_SELECTOR_UNIT:
961 case UVC_VC_PROCESSING_UNIT:
962 ret = uvc_parse_vc_processing_unit(dev, info, block, block_size);
964 case UVC_VC_EXTENSION_UNIT:
965 ret = uvc_parse_vc_extension_unit(dev, info, block, block_size);
968 ret = UVC_ERROR_INVALID_DEVICE;
976 * Process a VideoStreaming interface
979 uvc_error_t uvc_scan_streaming(uvc_device_t *dev,
980 uvc_device_info_t *info,
982 const struct libusb_interface_descriptor *if_desc;
983 const unsigned char *buffer;
984 size_t buffer_left, block_size;
985 uvc_error_t ret, parse_ret;
986 uvc_streaming_interface_t *stream_if;
992 if_desc = &(info->config->interface[interface_idx].altsetting[0]);
993 buffer = if_desc->extra;
994 buffer_left = if_desc->extra_length;
996 stream_if = calloc(1, sizeof(*stream_if));
997 stream_if->parent = info;
998 stream_if->bInterfaceNumber = if_desc->bInterfaceNumber;
999 DL_APPEND(info->stream_ifs, stream_if);
1001 while (buffer_left >= 3) {
1002 block_size = buffer[0];
1003 parse_ret = uvc_parse_vs(dev, info, stream_if, buffer, block_size);
1005 if (parse_ret != UVC_SUCCESS) {
1010 buffer_left -= block_size;
1011 buffer += block_size;
1019 * @brief Parse a VideoStreaming header block.
1022 uvc_error_t uvc_parse_vs_input_header(uvc_streaming_interface_t *stream_if,
1023 const unsigned char *block,
1024 size_t block_size) {
1027 stream_if->bEndpointAddress = block[6] & 0x8f;
1028 stream_if->bTerminalLink = block[8];
1030 UVC_EXIT(UVC_SUCCESS);
1035 * @brief Parse a VideoStreaming uncompressed format block.
1038 uvc_error_t uvc_parse_vs_format_uncompressed(uvc_streaming_interface_t *stream_if,
1039 const unsigned char *block,
1040 size_t block_size) {
1043 uvc_format_desc_t *format = calloc(1, sizeof(*format));
1045 format->parent = stream_if;
1046 format->bDescriptorSubtype = block[2];
1047 format->bFormatIndex = block[3];
1048 //format->bmCapabilities = block[4];
1049 //format->bmFlags = block[5];
1050 memcpy(format->guidFormat, &block[5], 16);
1051 format->bBitsPerPixel = block[21];
1052 format->bDefaultFrameIndex = block[22];
1053 format->bAspectRatioX = block[23];
1054 format->bAspectRatioY = block[24];
1055 format->bmInterlaceFlags = block[25];
1056 format->bCopyProtect = block[26];
1058 DL_APPEND(stream_if->format_descs, format);
1060 UVC_EXIT(UVC_SUCCESS);
1065 * @brief Parse a VideoStreaming MJPEG format block.
1068 uvc_error_t uvc_parse_vs_format_mjpeg(uvc_streaming_interface_t *stream_if,
1069 const unsigned char *block,
1070 size_t block_size) {
1073 uvc_format_desc_t *format = calloc(1, sizeof(*format));
1075 format->parent = stream_if;
1076 format->bDescriptorSubtype = block[2];
1077 format->bFormatIndex = block[3];
1078 memcpy(format->fourccFormat, "MJPG", 4);
1079 format->bmFlags = block[5];
1080 format->bBitsPerPixel = 0;
1081 format->bDefaultFrameIndex = block[6];
1082 format->bAspectRatioX = block[7];
1083 format->bAspectRatioY = block[8];
1084 format->bmInterlaceFlags = block[9];
1085 format->bCopyProtect = block[10];
1087 DL_APPEND(stream_if->format_descs, format);
1089 UVC_EXIT(UVC_SUCCESS);
1094 * @brief Parse a VideoStreaming uncompressed frame block.
1097 uvc_error_t uvc_parse_vs_frame_uncompressed(uvc_streaming_interface_t *stream_if,
1098 const unsigned char *block,
1099 size_t block_size) {
1100 uvc_format_desc_t *format;
1101 uvc_frame_desc_t *frame;
1103 const unsigned char *p;
1108 format = stream_if->format_descs->prev;
1109 frame = calloc(1, sizeof(*frame));
1111 frame->parent = format;
1113 frame->bDescriptorSubtype = block[2];
1114 frame->bFrameIndex = block[3];
1115 frame->bmCapabilities = block[4];
1116 frame->wWidth = block[5] + (block[6] << 8);
1117 frame->wHeight = block[7] + (block[8] << 8);
1118 frame->dwMinBitRate = DW_TO_INT(&block[9]);
1119 frame->dwMaxBitRate = DW_TO_INT(&block[13]);
1120 frame->dwMaxVideoFrameBufferSize = DW_TO_INT(&block[17]);
1121 frame->dwDefaultFrameInterval = DW_TO_INT(&block[21]);
1122 // frame->bFrameIntervalType = block[25];
1124 if (block[25] == 0) {
1125 frame->dwMinFrameInterval = DW_TO_INT(&block[26]);
1126 frame->dwMaxFrameInterval = DW_TO_INT(&block[30]);
1127 frame->dwFrameIntervalStep = DW_TO_INT(&block[34]);
1129 frame->intervals = calloc(block[25] + 1, sizeof(frame->intervals[0]));
1132 for (i = 0; i < block[25]; ++i) {
1133 frame->intervals[i] = DW_TO_INT(p);
1136 frame->intervals[block[25]] = 0;
1139 DL_APPEND(format->frame_descs, frame);
1141 UVC_EXIT(UVC_SUCCESS);
1146 * Process a single VideoStreaming descriptor block
1149 uvc_error_t uvc_parse_vs(
1151 uvc_device_info_t *info,
1152 uvc_streaming_interface_t *stream_if,
1153 const unsigned char *block, size_t block_size) {
1155 int descriptor_subtype;
1160 descriptor_subtype = block[2];
1162 switch (descriptor_subtype) {
1163 case UVC_VS_INPUT_HEADER:
1164 ret = uvc_parse_vs_input_header(stream_if, block, block_size);
1166 case UVC_VS_FORMAT_UNCOMPRESSED:
1167 ret = uvc_parse_vs_format_uncompressed(stream_if, block, block_size);
1169 case UVC_VS_FORMAT_MJPEG:
1170 ret = uvc_parse_vs_format_mjpeg(stream_if, block, block_size);
1172 case UVC_VS_FRAME_UNCOMPRESSED:
1173 case UVC_VS_FRAME_MJPEG:
1174 ret = uvc_parse_vs_frame_uncompressed(stream_if, block, block_size);
1177 /** @todo handle JPEG and maybe still frames or even DV... */
1186 * @brief Free memory associated with a UVC device
1187 * @pre Streaming must be stopped, and threads must have died
1189 void uvc_free_devh(uvc_device_handle_t *devh) {
1193 uvc_free_device_info(devh->info);
1195 if (devh->status_xfer)
1196 libusb_free_transfer(devh->status_xfer);
1203 /** @brief Close a device
1207 * Ends any stream that's in progress.
1209 * The device handle and frame structures will be invalidated.
1211 void uvc_close(uvc_device_handle_t *devh) {
1213 uvc_context_t *ctx = devh->dev->ctx;
1216 uvc_stop_streaming(devh);
1218 uvc_release_if(devh, devh->info->ctrl_if.bInterfaceNumber);
1220 /* If we are managing the libusb context and this is the last open device,
1221 * then we need to cancel the handler thread. When we call libusb_close,
1222 * it'll cause a return from the thread's libusb_handle_events call, after
1223 * which the handler thread will check the flag we set and then exit. */
1224 if (ctx->own_usb_ctx && ctx->open_devices == devh && devh->next == NULL) {
1225 ctx->kill_handler_thread = 1;
1226 libusb_close(devh->usb_devh);
1227 pthread_join(ctx->handler_thread, NULL);
1229 libusb_close(devh->usb_devh);
1232 DL_DELETE(ctx->open_devices, devh);
1234 uvc_unref_device(devh->dev);
1236 uvc_free_devh(devh);
1242 * @brief Get number of open devices
1244 size_t uvc_num_devices(uvc_context_t *ctx) {
1247 uvc_device_handle_t *devh;
1251 DL_FOREACH(ctx->open_devices, devh) {
1255 UVC_EXIT((int) count);
1259 void uvc_process_status_xfer(uvc_device_handle_t *devh, struct libusb_transfer *transfer) {
1260 enum uvc_status_class status_class;
1261 uint8_t originator = 0, selector = 0, event = 0;
1262 enum uvc_status_attribute attribute = UVC_STATUS_ATTRIBUTE_UNKNOWN;
1264 size_t data_len = 0;
1268 /* printf("Got transfer of aLen = %d\n", transfer->actual_length); */
1270 if (transfer->actual_length < 4) {
1271 UVC_DEBUG("Short read of status update (%d bytes)", transfer->actual_length);
1276 originator = transfer->buffer[1];
1278 switch (transfer->buffer[0] & 0x0f) {
1279 case 1: { /* VideoControl interface */
1280 int found_entity = 0;
1281 struct uvc_input_terminal *input_terminal;
1282 struct uvc_processing_unit *processing_unit;
1284 if (transfer->actual_length < 5) {
1285 UVC_DEBUG("Short read of VideoControl status update (%d bytes)",
1286 transfer->actual_length);
1291 event = transfer->buffer[2];
1292 selector = transfer->buffer[3];
1294 if (originator == 0) {
1295 UVC_DEBUG("Unhandled update from VC interface");
1297 return; /* @todo VideoControl virtual entity interface updates */
1301 UVC_DEBUG("Unhandled VC event %d", (int) event);
1306 /* printf("bSelector: %d\n", selector); */
1308 DL_FOREACH(devh->info->ctrl_if.input_term_descs, input_terminal) {
1309 if (input_terminal->bTerminalID == originator) {
1310 status_class = UVC_STATUS_CLASS_CONTROL_CAMERA;
1316 if (!found_entity) {
1317 DL_FOREACH(devh->info->ctrl_if.processing_unit_descs, processing_unit) {
1318 if (processing_unit->bUnitID == originator) {
1319 status_class = UVC_STATUS_CLASS_CONTROL_PROCESSING;
1326 if (!found_entity) {
1327 UVC_DEBUG("Got status update for unknown VideoControl entity %d",
1333 attribute = transfer->buffer[4];
1334 data = transfer->buffer + 5;
1335 data_len = transfer->actual_length - 5;
1338 case 2: /* VideoStreaming interface */
1339 UVC_DEBUG("Unhandled update from VideoStreaming interface");
1341 return; /* @todo VideoStreaming updates */
1344 UVC_DEBUG("Event: class=%d, event=%d, selector=%d, attribute=%d, data_len=%zd",
1345 status_class, event, selector, attribute, data_len);
1347 if(devh->status_cb) {
1348 UVC_DEBUG("Running user-supplied status callback");
1349 devh->status_cb(status_class,
1354 devh->status_user_ptr);
1361 * @brief Process asynchronous status updates from the device.
1363 void _uvc_status_callback(struct libusb_transfer *transfer) {
1366 uvc_device_handle_t *devh = (uvc_device_handle_t *) transfer->user_data;
1368 switch (transfer->status) {
1369 case LIBUSB_TRANSFER_ERROR:
1370 case LIBUSB_TRANSFER_CANCELLED:
1371 case LIBUSB_TRANSFER_NO_DEVICE:
1372 UVC_DEBUG("not processing/resubmitting, status = %d", transfer->status);
1375 case LIBUSB_TRANSFER_COMPLETED:
1376 uvc_process_status_xfer(devh, transfer);
1378 case LIBUSB_TRANSFER_TIMED_OUT:
1379 case LIBUSB_TRANSFER_STALL:
1380 case LIBUSB_TRANSFER_OVERFLOW:
1381 UVC_DEBUG("retrying transfer, status = %d", transfer->status);
1385 uvc_error_t ret = libusb_submit_transfer(transfer);
1386 UVC_DEBUG("libusb_submit_transfer() = %d", ret);
1391 /** @brief Set a callback function to receive status updates
1395 void uvc_set_status_callback(uvc_device_handle_t *devh,
1396 uvc_status_callback_t cb,
1400 devh->status_cb = cb;
1401 devh->status_user_ptr = user_ptr;