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
36 * @brief Support for finding, inspecting and opening UVC devices
39 #include "libuvc/libuvc.h"
40 #include "libuvc/libuvc_internal.h"
42 int uvc_already_open(uvc_context_t *ctx, struct libusb_device *usb_dev);
43 void uvc_free_devh(uvc_device_handle_t *devh);
45 uvc_error_t uvc_get_device_info(uvc_device_t *dev, uvc_device_info_t **info);
46 void uvc_free_device_info(uvc_device_info_t *info);
48 uvc_error_t uvc_scan_control(uvc_device_t *dev, uvc_device_info_t *info);
49 uvc_error_t uvc_parse_vc(uvc_device_t *dev,
50 uvc_device_info_t *info,
51 const unsigned char *block, size_t block_size);
52 uvc_error_t uvc_parse_vc_selector_unit(uvc_device_t *dev,
53 uvc_device_info_t *info,
54 const unsigned char *block, size_t block_size);
55 uvc_error_t uvc_parse_vc_extension_unit(uvc_device_t *dev,
56 uvc_device_info_t *info,
57 const unsigned char *block,
59 uvc_error_t uvc_parse_vc_header(uvc_device_t *dev,
60 uvc_device_info_t *info,
61 const unsigned char *block, size_t block_size);
62 uvc_error_t uvc_parse_vc_input_terminal(uvc_device_t *dev,
63 uvc_device_info_t *info,
64 const unsigned char *block,
66 uvc_error_t uvc_parse_vc_processing_unit(uvc_device_t *dev,
67 uvc_device_info_t *info,
68 const unsigned char *block,
71 uvc_error_t uvc_scan_streaming(uvc_device_t *dev,
72 uvc_device_info_t *info,
74 uvc_error_t uvc_parse_vs(uvc_device_t *dev,
75 uvc_device_info_t *info,
76 uvc_streaming_interface_t *stream_if,
77 const unsigned char *block, size_t block_size);
78 uvc_error_t uvc_parse_vs_format_uncompressed(uvc_streaming_interface_t *stream_if,
79 const unsigned char *block,
81 uvc_error_t uvc_parse_vs_format_mjpeg(uvc_streaming_interface_t *stream_if,
82 const unsigned char *block,
84 uvc_error_t uvc_parse_vs_frame_uncompressed(uvc_streaming_interface_t *stream_if,
85 const unsigned char *block,
87 uvc_error_t uvc_parse_vs_frame_format(uvc_streaming_interface_t *stream_if,
88 const unsigned char *block,
90 uvc_error_t uvc_parse_vs_frame_frame(uvc_streaming_interface_t *stream_if,
91 const unsigned char *block,
93 uvc_error_t uvc_parse_vs_input_header(uvc_streaming_interface_t *stream_if,
94 const unsigned char *block,
97 void LIBUSB_CALL _uvc_status_callback(struct libusb_transfer *transfer);
100 * @brief Test whether the specified USB device has been opened as a UVC device
103 * @param ctx Context in which to search for the UVC device
104 * @param usb_dev USB device to find
105 * @return true if the device is open in this context
107 int uvc_already_open(uvc_context_t *ctx, struct libusb_device *usb_dev) {
108 uvc_device_handle_t *devh;
110 DL_FOREACH(ctx->open_devices, devh) {
111 if (usb_dev == devh->dev->usb_dev)
118 /** @brief Finds a camera identified by vendor, product and/or serial number
121 * @param[in] ctx UVC context in which to search for the camera
122 * @param[out] dev Reference to the camera, or NULL if not found
123 * @param[in] vid Vendor ID number, optional
124 * @param[in] pid Product ID number, optional
125 * @param[in] sn Serial number or NULL
126 * @return Error finding device or UVC_SUCCESS
128 uvc_error_t uvc_find_device(
129 uvc_context_t *ctx, uvc_device_t **dev,
130 int vid, int pid, const char *sn) {
131 uvc_error_t ret = UVC_SUCCESS;
134 uvc_device_t *test_dev;
140 ret = uvc_get_device_list(ctx, &list);
142 if (ret != UVC_SUCCESS) {
150 while (!found_dev && (test_dev = list[dev_idx++]) != NULL) {
151 uvc_device_descriptor_t *desc;
153 if (uvc_get_device_descriptor(test_dev, &desc) != UVC_SUCCESS)
156 if ((!vid || desc->idVendor == vid)
157 && (!pid || desc->idProduct == pid)
158 && (!sn || (desc->serialNumber && !strcmp(desc->serialNumber, sn))))
161 uvc_free_device_descriptor(desc);
165 uvc_ref_device(test_dev);
167 uvc_free_device_list(list, 1);
171 UVC_EXIT(UVC_SUCCESS);
174 UVC_EXIT(UVC_ERROR_NO_DEVICE);
175 return UVC_ERROR_NO_DEVICE;
179 /** @brief Finds all cameras identified by vendor, product and/or serial number
182 * @param[in] ctx UVC context in which to search for the camera
183 * @param[out] devs List of matching cameras
184 * @param[in] vid Vendor ID number, optional
185 * @param[in] pid Product ID number, optional
186 * @param[in] sn Serial number or NULL
187 * @return Error finding device or UVC_SUCCESS
189 uvc_error_t uvc_find_devices(
190 uvc_context_t *ctx, uvc_device_t ***devs,
191 int vid, int pid, const char *sn) {
192 uvc_error_t ret = UVC_SUCCESS;
195 uvc_device_t *test_dev;
199 uvc_device_t **list_internal;
204 ret = uvc_get_device_list(ctx, &list);
206 if (ret != UVC_SUCCESS) {
215 list_internal = malloc(sizeof(*list_internal));
216 *list_internal = NULL;
218 while ((test_dev = list[dev_idx++]) != NULL) {
219 uvc_device_descriptor_t *desc;
221 if (uvc_get_device_descriptor(test_dev, &desc) != UVC_SUCCESS)
224 if ((!vid || desc->idVendor == vid)
225 && (!pid || desc->idProduct == pid)
226 && (!sn || (desc->serialNumber && !strcmp(desc->serialNumber, sn)))) {
228 uvc_ref_device(test_dev);
231 list_internal = realloc(list_internal, (num_uvc_devices + 1) * sizeof(*list_internal));
233 list_internal[num_uvc_devices - 1] = test_dev;
234 list_internal[num_uvc_devices] = NULL;
237 uvc_free_device_descriptor(desc);
240 uvc_free_device_list(list, 1);
243 *devs = list_internal;
244 UVC_EXIT(UVC_SUCCESS);
247 UVC_EXIT(UVC_ERROR_NO_DEVICE);
248 return UVC_ERROR_NO_DEVICE;
252 /** @brief Get the number of the bus to which the device is attached
255 uint8_t uvc_get_bus_number(uvc_device_t *dev) {
256 return libusb_get_bus_number(dev->usb_dev);
259 /** @brief Get the number assigned to the device within its bus
262 uint8_t uvc_get_device_address(uvc_device_t *dev) {
263 return libusb_get_device_address(dev->usb_dev);
266 /** @brief Open a UVC device
269 * @param dev Device to open
270 * @param[out] devh Handle on opened device
271 * @return Error opening device or SUCCESS
273 uvc_error_t uvc_open(
275 uvc_device_handle_t **devh) {
277 struct libusb_device_handle *usb_devh;
278 uvc_device_handle_t *internal_devh;
279 struct libusb_device_descriptor desc;
283 ret = libusb_open(dev->usb_dev, &usb_devh);
284 UVC_DEBUG("libusb_open() = %d", ret);
286 if (ret != UVC_SUCCESS) {
293 internal_devh = calloc(1, sizeof(*internal_devh));
294 internal_devh->dev = dev;
295 internal_devh->usb_devh = usb_devh;
297 ret = uvc_get_device_info(dev, &(internal_devh->info));
299 if (ret != UVC_SUCCESS)
302 UVC_DEBUG("claiming control interface %d", internal_devh->info->ctrl_if.bInterfaceNumber);
303 ret = uvc_claim_if(internal_devh, internal_devh->info->ctrl_if.bInterfaceNumber);
304 if (ret != UVC_SUCCESS)
307 libusb_get_device_descriptor(dev->usb_dev, &desc);
308 internal_devh->is_isight = (desc.idVendor == 0x05ac && desc.idProduct == 0x8501);
310 if (internal_devh->info->ctrl_if.bEndpointAddress) {
311 internal_devh->status_xfer = libusb_alloc_transfer(0);
312 if (!internal_devh->status_xfer) {
313 ret = UVC_ERROR_NO_MEM;
317 libusb_fill_interrupt_transfer(internal_devh->status_xfer,
319 internal_devh->info->ctrl_if.bEndpointAddress,
320 internal_devh->status_buf,
321 sizeof(internal_devh->status_buf),
322 _uvc_status_callback,
325 ret = libusb_submit_transfer(internal_devh->status_xfer);
326 UVC_DEBUG("libusb_submit_transfer() = %d", ret);
330 "uvc: device has a status interrupt endpoint, but unable to read from it\n");
335 if (dev->ctx->own_usb_ctx && dev->ctx->open_devices == NULL) {
336 /* Since this is our first device, we need to spawn the event handler thread */
337 uvc_start_handler_thread(dev->ctx);
340 DL_APPEND(dev->ctx->open_devices, internal_devh);
341 *devh = internal_devh;
348 if ( internal_devh->info ) {
349 uvc_release_if(internal_devh, internal_devh->info->ctrl_if.bInterfaceNumber);
351 libusb_close(usb_devh);
352 uvc_unref_device(dev);
353 uvc_free_devh(internal_devh);
362 * @brief Parses the complete device descriptor for a device
364 * @note Free *info with uvc_free_device_info when you're done
366 * @param dev Device to parse descriptor for
367 * @param info Where to store a pointer to the new info struct
369 uvc_error_t uvc_get_device_info(uvc_device_t *dev,
370 uvc_device_info_t **info) {
372 uvc_device_info_t *internal_info;
376 internal_info = calloc(1, sizeof(*internal_info));
377 if (!internal_info) {
378 UVC_EXIT(UVC_ERROR_NO_MEM);
379 return UVC_ERROR_NO_MEM;
382 if (libusb_get_config_descriptor(dev->usb_dev,
384 &(internal_info->config)) != 0) {
386 UVC_EXIT(UVC_ERROR_IO);
390 ret = uvc_scan_control(dev, internal_info);
391 if (ret != UVC_SUCCESS) {
392 uvc_free_device_info(internal_info);
397 *info = internal_info;
405 * @brief Frees the device descriptor for a device
408 * @param info Which device info block to free
410 void uvc_free_device_info(uvc_device_info_t *info) {
411 uvc_input_terminal_t *input_term, *input_term_tmp;
412 uvc_processing_unit_t *proc_unit, *proc_unit_tmp;
413 uvc_extension_unit_t *ext_unit, *ext_unit_tmp;
415 uvc_streaming_interface_t *stream_if, *stream_if_tmp;
416 uvc_format_desc_t *format, *format_tmp;
417 uvc_frame_desc_t *frame, *frame_tmp;
421 DL_FOREACH_SAFE(info->ctrl_if.input_term_descs, input_term, input_term_tmp) {
422 DL_DELETE(info->ctrl_if.input_term_descs, input_term);
426 DL_FOREACH_SAFE(info->ctrl_if.processing_unit_descs, proc_unit, proc_unit_tmp) {
427 DL_DELETE(info->ctrl_if.processing_unit_descs, proc_unit);
431 DL_FOREACH_SAFE(info->ctrl_if.extension_unit_descs, ext_unit, ext_unit_tmp) {
432 DL_DELETE(info->ctrl_if.extension_unit_descs, ext_unit);
436 DL_FOREACH_SAFE(info->stream_ifs, stream_if, stream_if_tmp) {
437 DL_FOREACH_SAFE(stream_if->format_descs, format, format_tmp) {
438 DL_FOREACH_SAFE(format->frame_descs, frame, frame_tmp) {
439 if (frame->intervals)
440 free(frame->intervals);
442 DL_DELETE(format->frame_descs, frame);
446 DL_DELETE(stream_if->format_descs, format);
450 DL_DELETE(info->stream_ifs, stream_if);
455 libusb_free_config_descriptor(info->config);
463 * @brief Get a descriptor that contains the general information about
467 * Free *desc with uvc_free_device_descriptor when you're done.
469 * @param dev Device to fetch information about
470 * @param[out] desc Descriptor structure
471 * @return Error if unable to fetch information, else SUCCESS
473 uvc_error_t uvc_get_device_descriptor(
475 uvc_device_descriptor_t **desc) {
476 uvc_device_descriptor_t *desc_internal;
477 struct libusb_device_descriptor usb_desc;
478 struct libusb_device_handle *usb_devh;
483 ret = libusb_get_device_descriptor(dev->usb_dev, &usb_desc);
485 if (ret != UVC_SUCCESS) {
490 desc_internal = calloc(1, sizeof(*desc_internal));
491 desc_internal->idVendor = usb_desc.idVendor;
492 desc_internal->idProduct = usb_desc.idProduct;
494 if (libusb_open(dev->usb_dev, &usb_devh) == 0) {
495 unsigned char buf[64];
497 int bytes = libusb_get_string_descriptor_ascii(
498 usb_devh, usb_desc.iSerialNumber, buf, sizeof(buf));
501 desc_internal->serialNumber = strdup((const char*) buf);
503 bytes = libusb_get_string_descriptor_ascii(
504 usb_devh, usb_desc.iManufacturer, buf, sizeof(buf));
507 desc_internal->manufacturer = strdup((const char*) buf);
509 bytes = libusb_get_string_descriptor_ascii(
510 usb_devh, usb_desc.iProduct, buf, sizeof(buf));
513 desc_internal->product = strdup((const char*) buf);
515 libusb_close(usb_devh);
517 UVC_DEBUG("can't open device %04x:%04x, not fetching serial etc.",
518 usb_desc.idVendor, usb_desc.idProduct);
521 *desc = desc_internal;
528 * @brief Frees a device descriptor created with uvc_get_device_descriptor
531 * @param desc Descriptor to free
533 void uvc_free_device_descriptor(
534 uvc_device_descriptor_t *desc) {
537 if (desc->serialNumber)
538 free((void*) desc->serialNumber);
540 if (desc->manufacturer)
541 free((void*) desc->manufacturer);
544 free((void*) desc->product);
552 * @brief Get a list of the UVC devices attached to the system
555 * @note Free the list with uvc_free_device_list when you're done.
557 * @param ctx UVC context in which to list devices
558 * @param list List of uvc_device structures
559 * @return Error if unable to list devices, else SUCCESS
561 uvc_error_t uvc_get_device_list(
563 uvc_device_t ***list) {
564 struct libusb_device **usb_dev_list;
565 struct libusb_device *usb_dev;
568 uvc_device_t **list_internal;
573 struct libusb_config_descriptor *config;
574 struct libusb_device_descriptor desc;
575 uint8_t got_interface;
579 const struct libusb_interface *interface;
583 const struct libusb_interface_descriptor *if_desc;
587 num_usb_devices = libusb_get_device_list(ctx->usb_ctx, &usb_dev_list);
589 if (num_usb_devices < 0) {
590 UVC_EXIT(UVC_ERROR_IO);
594 list_internal = malloc(sizeof(*list_internal));
595 *list_internal = NULL;
600 while ((usb_dev = usb_dev_list[++dev_idx]) != NULL) {
603 if (libusb_get_config_descriptor(usb_dev, 0, &config) != 0)
606 if ( libusb_get_device_descriptor ( usb_dev, &desc ) != LIBUSB_SUCCESS )
609 for (interface_idx = 0;
610 !got_interface && interface_idx < config->bNumInterfaces;
612 interface = &config->interface[interface_idx];
614 for (altsetting_idx = 0;
615 !got_interface && altsetting_idx < interface->num_altsetting;
617 if_desc = &interface->altsetting[altsetting_idx];
619 // Skip TIS cameras that definitely aren't UVC even though they might
622 if ( 0x199e == desc.idVendor && desc.idProduct >= 0x8201 &&
623 desc.idProduct <= 0x8208 ) {
627 // Special case for Imaging Source cameras
628 /* Video, Streaming */
629 if ( 0x199e == desc.idVendor && ( 0x8101 == desc.idProduct ||
630 0x8102 == desc.idProduct ) &&
631 if_desc->bInterfaceClass == 255 &&
632 if_desc->bInterfaceSubClass == 2 ) {
636 /* Video, Streaming */
637 if (if_desc->bInterfaceClass == 14 && if_desc->bInterfaceSubClass == 2) {
643 libusb_free_config_descriptor(config);
646 uvc_device_t *uvc_dev = malloc(sizeof(*uvc_dev));
649 uvc_dev->usb_dev = usb_dev;
650 uvc_ref_device(uvc_dev);
653 list_internal = realloc(list_internal, (num_uvc_devices + 1) * sizeof(*list_internal));
655 list_internal[num_uvc_devices - 1] = uvc_dev;
656 list_internal[num_uvc_devices] = NULL;
658 UVC_DEBUG(" UVC: %d", dev_idx);
660 UVC_DEBUG("non-UVC: %d", dev_idx);
664 libusb_free_device_list(usb_dev_list, 1);
666 *list = list_internal;
668 UVC_EXIT(UVC_SUCCESS);
673 * @brief Frees a list of device structures created with uvc_get_device_list.
676 * @param list Device list to free
677 * @param unref_devices Decrement the reference counter for each device
678 * in the list, and destroy any entries that end up with zero references
680 void uvc_free_device_list(uvc_device_t **list, uint8_t unref_devices) {
687 while ((dev = list[dev_idx++]) != NULL) {
688 uvc_unref_device(dev);
698 * @brief Get the uvc_device_t corresponding to an open device
701 * @note Unref the uvc_device_t when you're done with it
703 * @param devh Device handle to an open UVC device
705 uvc_device_t *uvc_get_device(uvc_device_handle_t *devh) {
706 uvc_ref_device(devh->dev);
711 * @brief Get the underlying libusb device handle for an open device
714 * This can be used to access other interfaces on the same device, e.g.
715 * a webcam microphone.
717 * @note The libusb device handle is only valid while the UVC device is open;
718 * it will be invalidated upon calling uvc_close.
720 * @param devh UVC device handle to an open device
722 libusb_device_handle *uvc_get_libusb_handle(uvc_device_handle_t *devh) {
723 return devh->usb_devh;
727 * @brief Get camera terminal descriptor for the open device.
729 * @note Do not modify the returned structure.
730 * @note The returned structure is part of a linked list, but iterating through
731 * it will make it no longer the camera terminal
733 * @param devh Device handle to an open UVC device
735 const uvc_input_terminal_t *uvc_get_camera_terminal(uvc_device_handle_t *devh) {
736 const uvc_input_terminal_t *term = uvc_get_input_terminals(devh);
737 while(term != NULL) {
738 if (term->wTerminalType == UVC_ITT_CAMERA) {
750 * @brief Get input terminal descriptors for the open device.
752 * @note Do not modify the returned structure.
753 * @note The returned structure is part of a linked list. Iterate through
754 * it by using the 'next' pointers.
756 * @param devh Device handle to an open UVC device
758 const uvc_input_terminal_t *uvc_get_input_terminals(uvc_device_handle_t *devh) {
759 return devh->info->ctrl_if.input_term_descs;
763 * @brief Get output terminal descriptors for the open device.
765 * @note Do not modify the returned structure.
766 * @note The returned structure is part of a linked list. Iterate through
767 * it by using the 'next' pointers.
769 * @param devh Device handle to an open UVC device
771 const uvc_output_terminal_t *uvc_get_output_terminals(uvc_device_handle_t *devh) {
772 return NULL; /* @todo */
776 * @brief Get selector unit descriptors for the open device.
778 * @note Do not modify the returned structure.
779 * @note The returned structure is part of a linked list. Iterate through
780 * it by using the 'next' pointers.
782 * @param devh Device handle to an open UVC device
784 const uvc_selector_unit_t *uvc_get_selector_units(uvc_device_handle_t *devh) {
785 return devh->info->ctrl_if.selector_unit_descs;
789 * @brief Get processing unit descriptors for the open device.
791 * @note Do not modify the returned structure.
792 * @note The returned structure is part of a linked list. Iterate through
793 * it by using the 'next' pointers.
795 * @param devh Device handle to an open UVC device
797 const uvc_processing_unit_t *uvc_get_processing_units(uvc_device_handle_t *devh) {
798 return devh->info->ctrl_if.processing_unit_descs;
802 * @brief Get extension unit descriptors for the open device.
804 * @note Do not modify the returned structure.
805 * @note The returned structure is part of a linked list. Iterate through
806 * it by using the 'next' pointers.
808 * @param devh Device handle to an open UVC device
810 const uvc_extension_unit_t *uvc_get_extension_units(uvc_device_handle_t *devh) {
811 return devh->info->ctrl_if.extension_unit_descs;
815 * @brief Increment the reference count for a device
818 * @param dev Device to reference
820 void uvc_ref_device(uvc_device_t *dev) {
824 libusb_ref_device(dev->usb_dev);
830 * @brief Decrement the reference count for a device
832 * @note If the count reaches zero, the device will be discarded
834 * @param dev Device to unreference
836 void uvc_unref_device(uvc_device_t *dev) {
839 libusb_unref_device(dev->usb_dev);
849 * Claim a UVC interface, detaching the kernel driver if necessary.
852 * @param devh UVC device handle
853 * @param idx UVC interface index
855 uvc_error_t uvc_claim_if(uvc_device_handle_t *devh, int idx) {
856 int ret = UVC_SUCCESS;
860 if ( devh->claimed & ( 1 << idx )) {
861 fprintf ( stderr, "attempt to claim already-claimed interface %d\n", idx );
866 /* Tell libusb to detach any active kernel drivers. libusb will keep track of whether
867 * it found a kernel driver for this interface. */
868 ret = libusb_detach_kernel_driver(devh->usb_devh, idx);
870 if (ret == UVC_SUCCESS || ret == LIBUSB_ERROR_NOT_FOUND || ret == LIBUSB_ERROR_NOT_SUPPORTED) {
871 UVC_DEBUG("claiming interface %d", idx);
872 if (!( ret = libusb_claim_interface(devh->usb_devh, idx))) {
873 devh->claimed |= ( 1 << idx );
876 UVC_DEBUG("not claiming interface %d: unable to detach kernel driver (%s)",
877 idx, uvc_strerror(ret));
885 * Release a UVC interface.
888 * @param devh UVC device handle
889 * @param idx UVC interface index
891 uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx) {
892 int ret = UVC_SUCCESS;
895 UVC_DEBUG("releasing interface %d", idx);
896 if (!( devh->claimed & ( 1 << idx ))) {
897 fprintf ( stderr, "attempt to release unclaimed interface %d\n", idx );
902 /* libusb_release_interface *should* reset the alternate setting to the first available,
903 but sometimes (e.g. on Darwin) it doesn't. Thus, we do it explicitly here.
904 This is needed to de-initialize certain cameras. */
905 libusb_set_interface_alt_setting(devh->usb_devh, idx, 0);
906 ret = libusb_release_interface(devh->usb_devh, idx);
908 if (UVC_SUCCESS == ret) {
909 devh->claimed &= ~( 1 << idx );
910 /* Reattach any kernel drivers that were disabled when we claimed this interface */
911 ret = libusb_attach_kernel_driver(devh->usb_devh, idx);
913 if (ret == UVC_SUCCESS) {
914 UVC_DEBUG("reattached kernel driver to interface %d", idx);
915 } else if (ret == LIBUSB_ERROR_NOT_FOUND || ret == LIBUSB_ERROR_NOT_SUPPORTED) {
916 ret = UVC_SUCCESS; /* NOT_FOUND and NOT_SUPPORTED are OK: nothing to do */
918 UVC_DEBUG("error reattaching kernel driver to interface %d: %s",
919 idx, uvc_strerror(ret));
928 * Find a device's VideoControl interface and process its descriptor
931 uvc_error_t uvc_scan_control(uvc_device_t *dev, uvc_device_info_t *info) {
932 const struct libusb_interface_descriptor *if_desc;
933 uvc_error_t parse_ret, ret;
935 const unsigned char *buffer;
936 size_t buffer_left, block_size;
943 uvc_device_descriptor_t* dev_desc;
944 int haveTISCamera = 0;
945 uvc_get_device_descriptor ( dev, &dev_desc );
946 if ( 0x199e == dev_desc->idVendor && ( 0x8101 == dev_desc->idProduct ||
947 0x8102 == dev_desc->idProduct )) {
950 uvc_free_device_descriptor ( dev_desc );
952 for (interface_idx = 0; interface_idx < info->config->bNumInterfaces; ++interface_idx) {
953 if_desc = &info->config->interface[interface_idx].altsetting[0];
955 if ( haveTISCamera && if_desc->bInterfaceClass == 255 && if_desc->bInterfaceSubClass == 1) // Video, Control
958 if (if_desc->bInterfaceClass == 14 && if_desc->bInterfaceSubClass == 1) // Video, Control
964 if (if_desc == NULL) {
965 UVC_EXIT(UVC_ERROR_INVALID_DEVICE);
966 return UVC_ERROR_INVALID_DEVICE;
969 info->ctrl_if.bInterfaceNumber = interface_idx;
970 if (if_desc->bNumEndpoints != 0) {
971 info->ctrl_if.bEndpointAddress = if_desc->endpoint[0].bEndpointAddress;
974 buffer = if_desc->extra;
975 buffer_left = if_desc->extra_length;
977 while (buffer_left >= 3) { // parseX needs to see buf[0,2] = length,type
978 block_size = buffer[0];
979 parse_ret = uvc_parse_vc(dev, info, buffer, block_size);
981 if (parse_ret != UVC_SUCCESS) {
986 buffer_left -= block_size;
987 buffer += block_size;
995 * @brief Parse a VideoControl header.
998 uvc_error_t uvc_parse_vc_header(uvc_device_t *dev,
999 uvc_device_info_t *info,
1000 const unsigned char *block, size_t block_size) {
1002 uvc_error_t scan_ret, ret = UVC_SUCCESS;
1008 uvc_version = (block[4] >> 4) * 1000 + (block[4] & 0x0f) * 100
1009 + (block[3] >> 4) * 10 + (block[3] & 0x0f);
1012 info->ctrl_if.bcdUVC = SW_TO_SHORT(&block[3]);
1014 switch (info->ctrl_if.bcdUVC) {
1016 info->ctrl_if.dwClockFrequency = DW_TO_INT(block + 7);
1018 info->ctrl_if.dwClockFrequency = DW_TO_INT(block + 7);
1022 UVC_EXIT(UVC_ERROR_NOT_SUPPORTED);
1023 return UVC_ERROR_NOT_SUPPORTED;
1026 for (i = 12; i < block_size; ++i) {
1027 scan_ret = uvc_scan_streaming(dev, info, block[i]);
1028 if (scan_ret != UVC_SUCCESS) {
1039 * @brief Parse a VideoControl input terminal.
1042 uvc_error_t uvc_parse_vc_input_terminal(uvc_device_t *dev,
1043 uvc_device_info_t *info,
1044 const unsigned char *block, size_t block_size) {
1045 uvc_input_terminal_t *term;
1050 /* only supporting camera-type input terminals */
1051 if (SW_TO_SHORT(&block[4]) != UVC_ITT_CAMERA) {
1052 UVC_EXIT(UVC_SUCCESS);
1056 term = calloc(1, sizeof(*term));
1058 term->bTerminalID = block[3];
1059 term->wTerminalType = SW_TO_SHORT(&block[4]);
1060 term->wObjectiveFocalLengthMin = SW_TO_SHORT(&block[8]);
1061 term->wObjectiveFocalLengthMax = SW_TO_SHORT(&block[10]);
1062 term->wOcularFocalLength = SW_TO_SHORT(&block[12]);
1064 for (i = 14 + block[14]; i >= 15; --i)
1065 term->bmControls = block[i] + (term->bmControls << 8);
1067 DL_APPEND(info->ctrl_if.input_term_descs, term);
1069 UVC_EXIT(UVC_SUCCESS);
1074 * @brief Parse a VideoControl processing unit.
1077 uvc_error_t uvc_parse_vc_processing_unit(uvc_device_t *dev,
1078 uvc_device_info_t *info,
1079 const unsigned char *block, size_t block_size) {
1080 uvc_processing_unit_t *unit;
1085 unit = calloc(1, sizeof(*unit));
1086 unit->bUnitID = block[3];
1087 unit->bSourceID = block[4];
1089 for (i = 7 + block[7]; i >= 8; --i)
1090 unit->bmControls = block[i] + (unit->bmControls << 8);
1092 DL_APPEND(info->ctrl_if.processing_unit_descs, unit);
1094 UVC_EXIT(UVC_SUCCESS);
1099 * @brief Parse a VideoControl selector unit.
1102 uvc_error_t uvc_parse_vc_selector_unit(uvc_device_t *dev,
1103 uvc_device_info_t *info,
1104 const unsigned char *block, size_t block_size) {
1105 uvc_selector_unit_t *unit;
1109 unit = calloc(1, sizeof(*unit));
1110 unit->bUnitID = block[3];
1112 DL_APPEND(info->ctrl_if.selector_unit_descs, unit);
1114 UVC_EXIT(UVC_SUCCESS);
1119 * @brief Parse a VideoControl extension unit.
1122 uvc_error_t uvc_parse_vc_extension_unit(uvc_device_t *dev,
1123 uvc_device_info_t *info,
1124 const unsigned char *block, size_t block_size) {
1125 uvc_extension_unit_t *unit = calloc(1, sizeof(*unit));
1126 const uint8_t *start_of_controls;
1127 int size_of_controls, num_in_pins;
1132 unit->bUnitID = block[3];
1133 memcpy(unit->guidExtensionCode, &block[4], 16);
1135 num_in_pins = block[21];
1136 size_of_controls = block[22 + num_in_pins];
1137 start_of_controls = &block[23 + num_in_pins];
1139 for (i = size_of_controls - 1; i >= 0; --i)
1140 unit->bmControls = start_of_controls[i] + (unit->bmControls << 8);
1142 DL_APPEND(info->ctrl_if.extension_unit_descs, unit);
1144 UVC_EXIT(UVC_SUCCESS);
1149 * Process a single VideoControl descriptor block
1152 uvc_error_t uvc_parse_vc(
1154 uvc_device_info_t *info,
1155 const unsigned char *block, size_t block_size) {
1156 int descriptor_subtype;
1157 uvc_error_t ret = UVC_SUCCESS;
1161 if (block[1] != 36) { // not a CS_INTERFACE descriptor??
1162 UVC_EXIT(UVC_SUCCESS);
1163 return UVC_SUCCESS; // UVC_ERROR_INVALID_DEVICE;
1166 descriptor_subtype = block[2];
1168 switch (descriptor_subtype) {
1170 ret = uvc_parse_vc_header(dev, info, block, block_size);
1172 case UVC_VC_INPUT_TERMINAL:
1173 ret = uvc_parse_vc_input_terminal(dev, info, block, block_size);
1175 case UVC_VC_OUTPUT_TERMINAL:
1177 case UVC_VC_SELECTOR_UNIT:
1178 ret = uvc_parse_vc_selector_unit(dev, info, block, block_size);
1180 case UVC_VC_PROCESSING_UNIT:
1181 ret = uvc_parse_vc_processing_unit(dev, info, block, block_size);
1183 case UVC_VC_EXTENSION_UNIT:
1184 ret = uvc_parse_vc_extension_unit(dev, info, block, block_size);
1187 ret = UVC_ERROR_INVALID_DEVICE;
1195 * Process a VideoStreaming interface
1198 uvc_error_t uvc_scan_streaming(uvc_device_t *dev,
1199 uvc_device_info_t *info,
1200 int interface_idx) {
1201 const struct libusb_interface_descriptor *if_desc;
1202 const unsigned char *buffer;
1203 size_t buffer_left, block_size;
1204 uvc_error_t ret, parse_ret;
1205 uvc_streaming_interface_t *stream_if;
1211 if_desc = &(info->config->interface[interface_idx].altsetting[0]);
1212 buffer = if_desc->extra;
1213 buffer_left = if_desc->extra_length;
1215 stream_if = calloc(1, sizeof(*stream_if));
1216 stream_if->parent = info;
1217 stream_if->bInterfaceNumber = if_desc->bInterfaceNumber;
1218 DL_APPEND(info->stream_ifs, stream_if);
1220 while (buffer_left >= 3) {
1221 block_size = buffer[0];
1222 parse_ret = uvc_parse_vs(dev, info, stream_if, buffer, block_size);
1224 if (parse_ret != UVC_SUCCESS) {
1229 buffer_left -= block_size;
1230 buffer += block_size;
1238 * @brief Parse a VideoStreaming header block.
1241 uvc_error_t uvc_parse_vs_input_header(uvc_streaming_interface_t *stream_if,
1242 const unsigned char *block,
1243 size_t block_size) {
1246 stream_if->bEndpointAddress = block[6] & 0x8f;
1247 stream_if->bTerminalLink = block[8];
1249 UVC_EXIT(UVC_SUCCESS);
1254 * @brief Parse a VideoStreaming uncompressed format block.
1257 uvc_error_t uvc_parse_vs_format_uncompressed(uvc_streaming_interface_t *stream_if,
1258 const unsigned char *block,
1259 size_t block_size) {
1262 uvc_format_desc_t *format = calloc(1, sizeof(*format));
1264 format->parent = stream_if;
1265 format->bDescriptorSubtype = block[2];
1266 format->bFormatIndex = block[3];
1267 //format->bmCapabilities = block[4];
1268 //format->bmFlags = block[5];
1269 memcpy(format->guidFormat, &block[5], 16);
1270 format->bBitsPerPixel = block[21];
1271 format->bDefaultFrameIndex = block[22];
1272 format->bAspectRatioX = block[23];
1273 format->bAspectRatioY = block[24];
1274 format->bmInterlaceFlags = block[25];
1275 format->bCopyProtect = block[26];
1277 DL_APPEND(stream_if->format_descs, format);
1279 UVC_EXIT(UVC_SUCCESS);
1284 * @brief Parse a VideoStreaming frame format block.
1287 uvc_error_t uvc_parse_vs_frame_format(uvc_streaming_interface_t *stream_if,
1288 const unsigned char *block,
1289 size_t block_size) {
1292 uvc_format_desc_t *format = calloc(1, sizeof(*format));
1294 format->parent = stream_if;
1295 format->bDescriptorSubtype = block[2];
1296 format->bFormatIndex = block[3];
1297 format->bNumFrameDescriptors = block[4];
1298 memcpy(format->guidFormat, &block[5], 16);
1299 format->bBitsPerPixel = block[21];
1300 format->bDefaultFrameIndex = block[22];
1301 format->bAspectRatioX = block[23];
1302 format->bAspectRatioY = block[24];
1303 format->bmInterlaceFlags = block[25];
1304 format->bCopyProtect = block[26];
1305 format->bVariableSize = block[27];
1307 DL_APPEND(stream_if->format_descs, format);
1309 UVC_EXIT(UVC_SUCCESS);
1314 * @brief Parse a VideoStreaming MJPEG format block.
1317 uvc_error_t uvc_parse_vs_format_mjpeg(uvc_streaming_interface_t *stream_if,
1318 const unsigned char *block,
1319 size_t block_size) {
1322 uvc_format_desc_t *format = calloc(1, sizeof(*format));
1324 format->parent = stream_if;
1325 format->bDescriptorSubtype = block[2];
1326 format->bFormatIndex = block[3];
1327 memcpy(format->fourccFormat, "MJPG", 4);
1328 format->bmFlags = block[5];
1329 format->bBitsPerPixel = 0;
1330 format->bDefaultFrameIndex = block[6];
1331 format->bAspectRatioX = block[7];
1332 format->bAspectRatioY = block[8];
1333 format->bmInterlaceFlags = block[9];
1334 format->bCopyProtect = block[10];
1336 DL_APPEND(stream_if->format_descs, format);
1338 UVC_EXIT(UVC_SUCCESS);
1343 * @brief Parse a VideoStreaming uncompressed frame block.
1346 uvc_error_t uvc_parse_vs_frame_frame(uvc_streaming_interface_t *stream_if,
1347 const unsigned char *block,
1348 size_t block_size) {
1349 uvc_format_desc_t *format;
1350 uvc_frame_desc_t *frame;
1352 const unsigned char *p;
1357 format = stream_if->format_descs->prev;
1358 frame = calloc(1, sizeof(*frame));
1360 frame->parent = format;
1362 frame->bDescriptorSubtype = block[2];
1363 frame->bFrameIndex = block[3];
1364 frame->bmCapabilities = block[4];
1365 frame->wWidth = block[5] + (block[6] << 8);
1366 frame->wHeight = block[7] + (block[8] << 8);
1367 frame->dwMinBitRate = DW_TO_INT(&block[9]);
1368 frame->dwMaxBitRate = DW_TO_INT(&block[13]);
1369 frame->dwDefaultFrameInterval = DW_TO_INT(&block[17]);
1370 frame->bFrameIntervalType = block[21];
1371 frame->dwBytesPerLine = DW_TO_INT(&block[22]);
1373 if (block[21] == 0) {
1374 frame->dwMinFrameInterval = DW_TO_INT(&block[26]);
1375 frame->dwMaxFrameInterval = DW_TO_INT(&block[30]);
1376 frame->dwFrameIntervalStep = DW_TO_INT(&block[34]);
1378 frame->intervals = calloc(block[21] + 1, sizeof(frame->intervals[0]));
1381 for (i = 0; i < block[21]; ++i) {
1382 frame->intervals[i] = DW_TO_INT(p);
1385 frame->intervals[block[21]] = 0;
1388 DL_APPEND(format->frame_descs, frame);
1390 UVC_EXIT(UVC_SUCCESS);
1395 * @brief Parse a VideoStreaming uncompressed frame block.
1398 uvc_error_t uvc_parse_vs_frame_uncompressed(uvc_streaming_interface_t *stream_if,
1399 const unsigned char *block,
1400 size_t block_size) {
1401 uvc_format_desc_t *format;
1402 uvc_frame_desc_t *frame;
1404 const unsigned char *p;
1409 format = stream_if->format_descs->prev;
1410 frame = calloc(1, sizeof(*frame));
1412 frame->parent = format;
1414 frame->bDescriptorSubtype = block[2];
1415 frame->bFrameIndex = block[3];
1416 frame->bmCapabilities = block[4];
1417 frame->wWidth = block[5] + (block[6] << 8);
1418 frame->wHeight = block[7] + (block[8] << 8);
1419 frame->dwMinBitRate = DW_TO_INT(&block[9]);
1420 frame->dwMaxBitRate = DW_TO_INT(&block[13]);
1421 frame->dwMaxVideoFrameBufferSize = DW_TO_INT(&block[17]);
1422 frame->dwDefaultFrameInterval = DW_TO_INT(&block[21]);
1423 frame->bFrameIntervalType = block[25];
1425 if (block[25] == 0) {
1426 frame->dwMinFrameInterval = DW_TO_INT(&block[26]);
1427 frame->dwMaxFrameInterval = DW_TO_INT(&block[30]);
1428 frame->dwFrameIntervalStep = DW_TO_INT(&block[34]);
1430 frame->intervals = calloc(block[25] + 1, sizeof(frame->intervals[0]));
1433 for (i = 0; i < block[25]; ++i) {
1434 frame->intervals[i] = DW_TO_INT(p);
1437 frame->intervals[block[25]] = 0;
1440 DL_APPEND(format->frame_descs, frame);
1442 UVC_EXIT(UVC_SUCCESS);
1447 * Process a single VideoStreaming descriptor block
1450 uvc_error_t uvc_parse_vs(
1452 uvc_device_info_t *info,
1453 uvc_streaming_interface_t *stream_if,
1454 const unsigned char *block, size_t block_size) {
1456 int descriptor_subtype;
1461 descriptor_subtype = block[2];
1463 switch (descriptor_subtype) {
1464 case UVC_VS_INPUT_HEADER:
1465 ret = uvc_parse_vs_input_header(stream_if, block, block_size);
1467 case UVC_VS_OUTPUT_HEADER:
1468 fprintf ( stderr, "unsupported descriptor subtype VS_OUTPUT_HEADER\n" );
1470 case UVC_VS_STILL_IMAGE_FRAME:
1471 fprintf ( stderr, "unsupported descriptor subtype VS_STILL_IMAGE_FRAME\n" );
1473 case UVC_VS_FORMAT_UNCOMPRESSED:
1474 ret = uvc_parse_vs_format_uncompressed(stream_if, block, block_size);
1476 case UVC_VS_FORMAT_MJPEG:
1477 ret = uvc_parse_vs_format_mjpeg(stream_if, block, block_size);
1479 case UVC_VS_FRAME_UNCOMPRESSED:
1480 case UVC_VS_FRAME_MJPEG:
1481 ret = uvc_parse_vs_frame_uncompressed(stream_if, block, block_size);
1483 case UVC_VS_FORMAT_MPEG2TS:
1484 fprintf ( stderr, "unsupported descriptor subtype VS_FORMAT_MPEG2TS\n" );
1486 case UVC_VS_FORMAT_DV:
1487 fprintf ( stderr, "unsupported descriptor subtype VS_FORMAT_DV\n" );
1489 case UVC_VS_COLORFORMAT:
1490 fprintf ( stderr, "unsupported descriptor subtype VS_COLORFORMAT\n" );
1492 case UVC_VS_FORMAT_FRAME_BASED:
1493 ret = uvc_parse_vs_frame_format ( stream_if, block, block_size );
1495 case UVC_VS_FRAME_FRAME_BASED:
1496 ret = uvc_parse_vs_frame_frame ( stream_if, block, block_size );
1498 case UVC_VS_FORMAT_STREAM_BASED:
1499 fprintf ( stderr, "unsupported descriptor subtype VS_FORMAT_STREAM_BASED\n" );
1502 /** @todo handle JPEG and maybe still frames or even DV... */
1503 //fprintf ( stderr, "unsupported descriptor subtype: %d\n",descriptor_subtype );
1512 * @brief Free memory associated with a UVC device
1513 * @pre Streaming must be stopped, and threads must have died
1515 void uvc_free_devh(uvc_device_handle_t *devh) {
1519 uvc_free_device_info(devh->info);
1521 if (devh->status_xfer)
1522 libusb_free_transfer(devh->status_xfer);
1529 /** @brief Close a device
1533 * Ends any stream that's in progress.
1535 * The device handle and frame structures will be invalidated.
1537 void uvc_close(uvc_device_handle_t *devh) {
1539 uvc_context_t *ctx = devh->dev->ctx;
1542 uvc_stop_streaming(devh);
1544 uvc_release_if(devh, devh->info->ctrl_if.bInterfaceNumber);
1546 /* If we are managing the libusb context and this is the last open device,
1547 * then we need to cancel the handler thread. When we call libusb_close,
1548 * it'll cause a return from the thread's libusb_handle_events call, after
1549 * which the handler thread will check the flag we set and then exit. */
1550 if (ctx->own_usb_ctx && ctx->open_devices == devh && devh->next == NULL) {
1551 ctx->kill_handler_thread = 1;
1552 libusb_close(devh->usb_devh);
1553 pthread_join(ctx->handler_thread, NULL);
1555 libusb_close(devh->usb_devh);
1558 DL_DELETE(ctx->open_devices, devh);
1560 uvc_unref_device(devh->dev);
1562 uvc_free_devh(devh);
1568 * @brief Get number of open devices
1570 size_t uvc_num_devices(uvc_context_t *ctx) {
1573 uvc_device_handle_t *devh;
1577 DL_FOREACH(ctx->open_devices, devh) {
1581 UVC_EXIT((int) count);
1585 void uvc_process_control_status(uvc_device_handle_t *devh, unsigned char *data, int len) {
1586 enum uvc_status_class status_class;
1587 uint8_t originator = 0, selector = 0, event = 0;
1588 enum uvc_status_attribute attribute = UVC_STATUS_ATTRIBUTE_UNKNOWN;
1589 void *content = NULL;
1590 size_t content_len = 0;
1591 int found_entity = 0;
1592 struct uvc_input_terminal *input_terminal;
1593 struct uvc_processing_unit *processing_unit;
1598 UVC_DEBUG("Short read of VideoControl status update (%d bytes)", len);
1603 originator = data[1];
1607 if (originator == 0) {
1608 UVC_DEBUG("Unhandled update from VC interface");
1610 return; /* @todo VideoControl virtual entity interface updates */
1614 UVC_DEBUG("Unhandled VC event %d", (int) event);
1619 /* printf("bSelector: %d\n", selector); */
1621 DL_FOREACH(devh->info->ctrl_if.input_term_descs, input_terminal) {
1622 if (input_terminal->bTerminalID == originator) {
1623 status_class = UVC_STATUS_CLASS_CONTROL_CAMERA;
1629 if (!found_entity) {
1630 DL_FOREACH(devh->info->ctrl_if.processing_unit_descs, processing_unit) {
1631 if (processing_unit->bUnitID == originator) {
1632 status_class = UVC_STATUS_CLASS_CONTROL_PROCESSING;
1639 if (!found_entity) {
1640 UVC_DEBUG("Got status update for unknown VideoControl entity %d",
1646 attribute = data[4];
1648 content_len = len - 5;
1650 UVC_DEBUG("Event: class=%d, event=%d, selector=%d, attribute=%d, content_len=%zd",
1651 status_class, event, selector, attribute, content_len);
1653 if(devh->status_cb) {
1654 UVC_DEBUG("Running user-supplied status callback");
1655 devh->status_cb(status_class,
1659 content, content_len,
1660 devh->status_user_ptr);
1666 void uvc_process_streaming_status(uvc_device_handle_t *devh, unsigned char *data, int len) {
1671 UVC_DEBUG("Invalid streaming status event received.\n");
1678 UVC_DEBUG("Short read of status update (%d bytes)", len);
1682 UVC_DEBUG("Button (intf %u) %s len %d\n", data[1], data[3] ? "pressed" : "released", len);
1684 if(devh->button_cb) {
1685 UVC_DEBUG("Running user-supplied button callback");
1686 devh->button_cb(data[1],
1688 devh->button_user_ptr);
1691 UVC_DEBUG("Stream %u error event %02x %02x len %d.\n", data[1], data[2], data[3], len);
1697 void uvc_process_status_xfer(uvc_device_handle_t *devh, struct libusb_transfer *transfer) {
1701 /* printf("Got transfer of aLen = %d\n", transfer->actual_length); */
1703 if (transfer->actual_length > 0) {
1704 switch (transfer->buffer[0] & 0x0f) {
1705 case 1: /* VideoControl interface */
1706 uvc_process_control_status(devh, transfer->buffer, transfer->actual_length);
1708 case 2: /* VideoStreaming interface */
1709 uvc_process_streaming_status(devh, transfer->buffer, transfer->actual_length);
1718 * @brief Process asynchronous status updates from the device.
1720 void LIBUSB_CALL _uvc_status_callback(struct libusb_transfer *transfer) {
1723 uvc_device_handle_t *devh = (uvc_device_handle_t *) transfer->user_data;
1725 switch (transfer->status) {
1726 case LIBUSB_TRANSFER_ERROR:
1727 case LIBUSB_TRANSFER_CANCELLED:
1728 case LIBUSB_TRANSFER_NO_DEVICE:
1729 UVC_DEBUG("not processing/resubmitting, status = %d", transfer->status);
1732 case LIBUSB_TRANSFER_COMPLETED:
1733 uvc_process_status_xfer(devh, transfer);
1735 case LIBUSB_TRANSFER_TIMED_OUT:
1736 case LIBUSB_TRANSFER_STALL:
1737 case LIBUSB_TRANSFER_OVERFLOW:
1738 UVC_DEBUG("retrying transfer, status = %d", transfer->status);
1742 #ifdef UVC_DEBUGGING
1745 libusb_submit_transfer(transfer);
1746 UVC_DEBUG("libusb_submit_transfer() = %d", ret);
1751 /** @brief Set a callback function to receive status updates
1755 void uvc_set_status_callback(uvc_device_handle_t *devh,
1756 uvc_status_callback_t cb,
1760 devh->status_cb = cb;
1761 devh->status_user_ptr = user_ptr;
1766 /** @brief Set a callback function to receive button events
1770 void uvc_set_button_callback(uvc_device_handle_t *devh,
1771 uvc_button_callback_t cb,
1775 devh->button_cb = cb;
1776 devh->button_user_ptr = user_ptr;
1782 * @brief Get format descriptions for the open device.
1784 * @note Do not modify the returned structure.
1786 * @param devh Device handle to an open UVC device
1788 const uvc_format_desc_t *uvc_get_format_descs(uvc_device_handle_t *devh) {
1789 return devh->info->stream_ifs->format_descs;