1 /*********************************************************************
2 *********************************************************************/
3 /*********************************************************************
4 * add and modified some functions to support non-rooted Android devices
5 * and modified some function for optimaization with gcc
6 * Copyright (C) 2014-2016 saki@serenegiant All rights reserved.
7 *********************************************************************/
8 /*********************************************************************
9 * Software License Agreement (BSD License)
11 * Copyright (C) 2010-2012 Ken Tossell
12 * All rights reserved.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
18 * * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * * Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials provided
23 * with the distribution.
24 * * Neither the name of the author nor other contributors may be
25 * used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 *********************************************************************/
42 * @defgroup device Device handling and enumeration
43 * @brief Support for finding, inspecting and opening UVC devices
48 #define LOG_TAG "libuvc/device"
49 #if 1 // デバッグ情報を出さない時1
51 #define LOG_NDEBUG // LOGV/LOGD/MARKを出力しない時
53 #undef USE_LOGALL // 指定したLOGxだけを出力
58 #define GET_RAW_DESCRIPTOR
61 #include "libuvc/libuvc.h"
62 #include "libuvc/libuvc_internal.h"
64 #define UVC_DETACH_ATTACH 0 // set this 1 attach/detach kernel driver by libuvc, set this 0 automatically attach/detach by libusb
66 int uvc_already_open(uvc_context_t *ctx, struct libusb_device *usb_dev);
67 void uvc_free_devh(uvc_device_handle_t *devh);
69 uvc_error_t uvc_get_device_info(uvc_device_t *dev, uvc_device_info_t **info);
70 void uvc_free_device_info(uvc_device_info_t *info);
72 uvc_error_t uvc_scan_control(uvc_device_t *dev, uvc_device_info_t *info);
73 uvc_error_t uvc_parse_vc(uvc_device_t *dev, uvc_device_info_t *info,
74 const unsigned char *block, size_t block_size);
75 uvc_error_t uvc_parse_vc_extension_unit(uvc_device_t *dev,
76 uvc_device_info_t *info, const unsigned char *block, size_t block_size);
77 uvc_error_t uvc_parse_vc_header(uvc_device_t *dev, uvc_device_info_t *info,
78 const unsigned char *block, size_t block_size);
79 uvc_error_t uvc_parse_vc_input_terminal(uvc_device_t *dev,
80 uvc_device_info_t *info, const unsigned char *block, size_t block_size);
81 uvc_error_t uvc_parse_vc_processing_unit(uvc_device_t *dev,
82 uvc_device_info_t *info, const unsigned char *block, size_t block_size);
84 uvc_error_t uvc_scan_streaming(uvc_device_t *dev, uvc_device_info_t *info,
86 uvc_error_t uvc_parse_vs(uvc_device_t *dev, uvc_device_info_t *info,
87 uvc_streaming_interface_t *stream_if, const unsigned char *block,
89 uvc_error_t uvc_parse_vs_format_uncompressed(
90 uvc_streaming_interface_t *stream_if, const unsigned char *block,
92 uvc_error_t uvc_parse_vs_format_mjpeg(uvc_streaming_interface_t *stream_if,
93 const unsigned char *block, size_t block_size);
94 uvc_error_t uvc_parse_vs_frame_uncompressed(
95 uvc_streaming_interface_t *stream_if, const unsigned char *block,
97 uvc_error_t uvc_parse_vs_frame_format(uvc_streaming_interface_t *stream_if,
98 const unsigned char *block,
100 uvc_error_t uvc_parse_vs_frame_frame(uvc_streaming_interface_t *stream_if,
101 const unsigned char *block,
103 uvc_error_t uvc_parse_vs_input_header(uvc_streaming_interface_t *stream_if,
104 const unsigned char *block, size_t block_size);
106 void _uvc_status_callback(struct libusb_transfer *transfer);
109 * @brief Test whether the specified USB device has been opened as a UVC device
112 * @param ctx Context in which to search for the UVC device
113 * @param usb_dev USB device to find
114 * @return true if the device is open in this context
116 int uvc_already_open(uvc_context_t *ctx, struct libusb_device *usb_dev) {
117 uvc_device_handle_t *devh;
119 DL_FOREACH(ctx->open_devices, devh)
121 if (usb_dev == devh->dev->usb_dev)
128 /** @brief Finds a camera identified by vendor, product and/or serial number
131 * @param[in] ctx UVC context in which to search for the camera
132 * @param[out] dev Reference to the camera, or NULL if not found
133 * @param[in] vid Vendor ID number, optional
134 * @param[in] pid Product ID number, optional
135 * @param[in] sn Serial number or NULL
136 * @return Error finding device or UVC_SUCCESS
138 uvc_error_t uvc_find_device(uvc_context_t *ctx, uvc_device_t **dev, int vid,
139 int pid, const char *sn) {
140 uvc_error_t ret = UVC_SUCCESS;
143 uvc_device_t *test_dev;
149 ret = uvc_get_device_list(ctx, &list);
151 if (UNLIKELY(ret != UVC_SUCCESS)) {
159 while (!found_dev && (test_dev = list[dev_idx++]) != NULL ) {
160 uvc_device_descriptor_t *desc;
162 if (uvc_get_device_descriptor(test_dev, &desc) != UVC_SUCCESS)
165 if ((!vid || desc->idVendor == vid) && (!pid || desc->idProduct == pid)
166 && (!sn || (desc->serialNumber && !strcmp(desc->serialNumber, sn))))
169 uvc_free_device_descriptor(desc);
173 uvc_ref_device(test_dev);
175 uvc_free_device_list(list, 1);
179 UVC_EXIT(UVC_SUCCESS);
182 UVC_EXIT(UVC_ERROR_NO_DEVICE);
183 return UVC_ERROR_NO_DEVICE;
188 * XXX add for non-rooted Android devices
189 * get uvc_device_t from specified vid/pid/serial
190 * return UVC_ERROR_NO_DEVICE when device not found
191 * return UVC_SUCCESS and set uvc_device_t when specific device found
193 uvc_error_t uvc_find_device2(uvc_context_t *ctx, uvc_device_t **device, int vid,
194 int pid, const char *sn, int fd) {
198 LOGD("call libusb_find_device");
199 struct libusb_device *usb_dev = libusb_find_device(ctx->usb_ctx, vid, pid, sn, fd);
202 *device = malloc(sizeof(uvc_device_t/* *device */));
203 (*device)->ctx = ctx;
205 (*device)->usb_dev = usb_dev;
206 libusb_set_device_fd(usb_dev, fd); // assign fd to libusb_device for non-rooted Android devices
207 uvc_ref_device(*device);
208 UVC_EXIT(UVC_SUCCESS);
211 LOGE("could not find specific device");
214 UVC_EXIT(UVC_ERROR_NO_DEVICE);
215 return UVC_ERROR_NO_DEVICE;
219 * XXX add for non-rooted Android device, >= Android7
220 * generate fake libusb_device according to specific params
221 * and set it to uvc_device_t to access UVC device on Android7 or later
223 uvc_error_t uvc_get_device_with_fd(uvc_context_t *ctx, uvc_device_t **device,
224 int vid, int pid, const char *serial, int fd, int busnum, int devaddr) {
228 LOGD("call libusb_get_device_with_fd");
229 struct libusb_device *usb_dev = libusb_get_device_with_fd(ctx->usb_ctx, vid, pid, serial, fd, busnum, devaddr);
231 if (LIKELY(usb_dev)) {
232 *device = malloc(sizeof(uvc_device_t/* *device */));
233 (*device)->ctx = ctx;
235 (*device)->usb_dev = usb_dev;
236 // libusb_set_device_fd(usb_dev, fd); // assign fd to libusb_device for non-rooted Android devices
237 uvc_ref_device(*device);
238 UVC_EXIT(UVC_SUCCESS);
239 RETURN(UVC_SUCCESS, int);
241 LOGE("could not find specific device");
243 RETURN(UVC_ERROR_NO_DEVICE, int);
248 /** @brief Get the number of the bus to which the device is attached
251 uint8_t uvc_get_bus_number(uvc_device_t *dev) {
252 return libusb_get_bus_number(dev->usb_dev);
255 /** @brief Get the number assigned to the device within its bus
258 uint8_t uvc_get_device_address(uvc_device_t *dev) {
259 return libusb_get_device_address(dev->usb_dev);
262 /** @brief Open a UVC device
265 * @param dev Device to open
266 * @param[out] devh Handle on opened device
267 * @return Error opening device or SUCCESS
269 uvc_error_t uvc_open(uvc_device_t *dev, uvc_device_handle_t **devh) {
271 struct libusb_device_handle *usb_devh;
272 uvc_device_handle_t *internal_devh;
273 struct libusb_device_descriptor desc;
277 ret = libusb_open(dev->usb_dev, &usb_devh);
278 UVC_DEBUG("libusb_open() = %d", ret);
280 if (UNLIKELY(ret != UVC_SUCCESS)) {
287 internal_devh = calloc(1, sizeof(*internal_devh));
288 internal_devh->dev = dev;
289 internal_devh->usb_devh = usb_devh;
290 internal_devh->reset_on_release_if = 0; // XXX
291 ret = uvc_get_device_info(dev, &(internal_devh->info));
292 pthread_mutex_init(&internal_devh->status_mutex, NULL); // XXX saki
294 if (UNLIKELY(ret != UVC_SUCCESS))
295 goto fail2; // uvc_claim_if was not called yet and we don't need to call uvc_release_if
296 #if !UVC_DETACH_ATTACH
297 /* enable automatic attach/detach kernel driver on supported platforms in libusb */
298 libusb_set_auto_detach_kernel_driver(usb_devh, 1);
300 UVC_DEBUG("claiming control interface %d",
301 internal_devh->info->ctrl_if.bInterfaceNumber);
302 ret = uvc_claim_if(internal_devh,
303 internal_devh->info->ctrl_if.bInterfaceNumber);
304 if (UNLIKELY(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 UVC_DEBUG("status check transfer:bEndpointAddress=0x%02x", internal_devh->info->ctrl_if.bEndpointAddress);
312 internal_devh->status_xfer = libusb_alloc_transfer(0);
313 if (UNLIKELY(!internal_devh->status_xfer)) {
314 ret = UVC_ERROR_NO_MEM;
318 libusb_fill_interrupt_transfer(internal_devh->status_xfer, usb_devh,
319 internal_devh->info->ctrl_if.bEndpointAddress,
320 internal_devh->status_buf, sizeof(internal_devh->status_buf),
321 _uvc_status_callback, internal_devh, 0);
322 ret = libusb_submit_transfer(internal_devh->status_xfer);
323 UVC_DEBUG("libusb_submit_transfer() = %d", ret);
326 LOGE("device has a status interrupt endpoint, but unable to read from it");
330 LOGE("internal_devh->info->ctrl_if.bEndpointAddress is null");
333 if (dev->ctx->own_usb_ctx && dev->ctx->open_devices == NULL) {
334 /* Since this is our first device, we need to spawn the event handler thread */
335 uvc_start_handler_thread(dev->ctx);
338 DL_APPEND(dev->ctx->open_devices, internal_devh);
339 *devh = internal_devh;
346 uvc_release_if(internal_devh, internal_devh->info->ctrl_if.bInterfaceNumber); // XXX crash, assume when uvc_get_device_info failed.
348 #if !UVC_DETACH_ATTACH
349 /* disable automatic attach/detach kernel driver on supported platforms in libusb */
350 libusb_set_auto_detach_kernel_driver(usb_devh, 0);
352 libusb_close(usb_devh);
353 uvc_unref_device(dev);
354 uvc_free_devh(internal_devh);
363 * @brief Parses the complete device descriptor for a device
365 * @note Free *info with uvc_free_device_info when you're done
367 * @param dev Device to parse descriptor for
368 * @param info Where to store a pointer to the new info struct
370 uvc_error_t uvc_get_device_info(uvc_device_t *dev, 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;
381 if (libusb_get_config_descriptor(dev->usb_dev, 0, &(internal_info->config)) != 0) {
382 // if (libusb_get_active_config_descriptor(dev->usb_dev, &(internal_info->config)) != 0) {
383 // XXX assume libusb_get_active_config_descriptor is better
384 // but some buggy device will return error when get active config.
385 // so we will use libusb_get_config_descriptor...
387 UVC_EXIT(UVC_ERROR_IO);
391 ret = uvc_scan_control(dev, internal_info);
393 uvc_free_device_info(internal_info);
398 *info = internal_info;
406 * @brief Frees the device descriptor for a device
409 * @param info Which device info block to free
411 void uvc_free_device_info(uvc_device_info_t *info) {
412 uvc_input_terminal_t *input_term, *input_term_tmp;
413 uvc_output_terminal_t *output_term, *output_term_tmp;
414 uvc_processing_unit_t *proc_unit, *proc_unit_tmp;
415 uvc_extension_unit_t *ext_unit, *ext_unit_tmp;
417 uvc_streaming_interface_t *stream_if, *stream_if_tmp;
418 uvc_format_desc_t *format, *format_tmp;
419 uvc_frame_desc_t *frame, *frame_tmp;
423 DL_FOREACH_SAFE(info->ctrl_if.input_term_descs, input_term, input_term_tmp)
425 DL_DELETE(info->ctrl_if.input_term_descs, input_term);
429 DL_FOREACH_SAFE(info->ctrl_if.output_term_descs, output_term, output_term_tmp)
431 DL_DELETE(info->ctrl_if.output_term_descs, output_term);
435 DL_FOREACH_SAFE(info->ctrl_if.processing_unit_descs, proc_unit, proc_unit_tmp)
437 DL_DELETE(info->ctrl_if.processing_unit_descs, proc_unit);
441 DL_FOREACH_SAFE(info->ctrl_if.extension_unit_descs, ext_unit, ext_unit_tmp)
443 DL_DELETE(info->ctrl_if.extension_unit_descs, ext_unit);
447 DL_FOREACH_SAFE(info->stream_ifs, stream_if, stream_if_tmp)
449 DL_FOREACH_SAFE(stream_if->format_descs, format, format_tmp)
451 DL_FOREACH_SAFE(format->frame_descs, frame, frame_tmp)
453 if (frame->intervals)
454 free(frame->intervals);
456 DL_DELETE(format->frame_descs, frame);
460 DL_DELETE(stream_if->format_descs, format);
464 DL_DELETE(info->stream_ifs, stream_if);
465 free(stream_if->bmaControls); // XXX
470 libusb_free_config_descriptor(info->config);
478 * @brief Get a descriptor that contains the general information about
482 * Free *desc with uvc_free_device_descriptor when you're done.
484 * @param dev Device to fetch information about
485 * @param[out] desc Descriptor structure
486 * @return Error if unable to fetch information, else SUCCESS
488 uvc_error_t uvc_get_device_descriptor(uvc_device_t *dev,
489 uvc_device_descriptor_t **desc) {
491 uvc_device_descriptor_t *desc_internal;
492 struct libusb_device_descriptor usb_desc;
493 struct libusb_device_handle *usb_devh;
498 ret = libusb_get_device_descriptor(dev->usb_dev, &usb_desc);
505 desc_internal = calloc(1, sizeof(*desc_internal));
506 desc_internal->idVendor = usb_desc.idVendor;
507 desc_internal->idProduct = usb_desc.idProduct;
509 if (libusb_open(dev->usb_dev, &usb_devh) == 0) {
510 unsigned char str_buf[255]; // XXX 64 => 255
512 int str_bytes = libusb_get_string_descriptor_ascii(usb_devh,
513 usb_desc.iSerialNumber, str_buf, sizeof(str_buf));
516 desc_internal->serialNumber = strdup((const char*) str_buf);
519 str_bytes = libusb_get_string_descriptor_ascii(usb_devh,
520 usb_desc.iManufacturer, str_buf, sizeof(str_buf));
523 desc_internal->manufacturer = strdup((const char*) str_buf);
526 str_bytes = libusb_get_string_descriptor_ascii(usb_devh,
527 usb_desc.iProduct, str_buf, sizeof(str_buf));
530 desc_internal->product = strdup((const char*) str_buf);
532 libusb_close(usb_devh);
534 UVC_DEBUG("can't open device %04x:%04x, not fetching serial",
535 usb_desc.idVendor, usb_desc.idProduct);
538 *desc = desc_internal;
545 * @brief Frees a device descriptor created with uvc_get_device_descriptor
548 * @param desc Descriptor to free
550 void uvc_free_device_descriptor(uvc_device_descriptor_t *desc) {
553 if (desc->serialNumber)
554 free((void*) desc->serialNumber);
556 if (desc->manufacturer)
557 free((void*) desc->manufacturer);
560 free((void*) desc->product);
568 * @brief Get a list of the UVC devices attached to the system
571 * @note Free the list with uvc_free_device_list when you're done.
573 * @param ctx UVC context in which to list devices
574 * @param list List of uvc_device structures
575 * @return Error if unable to list devices, else SUCCESS
577 uvc_error_t uvc_get_device_list(uvc_context_t *ctx, uvc_device_t ***list) {
579 struct libusb_device **usb_dev_list;
580 struct libusb_device *usb_dev;
583 uvc_device_t **list_internal;
588 struct libusb_device_handle *usb_devh;
589 struct libusb_config_descriptor *config;
590 struct libusb_device_descriptor desc;
591 uint8_t got_interface;
595 const struct libusb_interface *interface;
599 const struct libusb_interface_descriptor *if_desc;
603 num_usb_devices = libusb_get_device_list(ctx->usb_ctx, &usb_dev_list);
605 if (UNLIKELY(num_usb_devices < 0)) {
606 UVC_EXIT(UVC_ERROR_IO);
610 list_internal = malloc(sizeof(*list_internal));
611 *list_internal = NULL;
616 while ((usb_dev = usb_dev_list[++dev_idx]) != NULL ) {
620 if (libusb_get_config_descriptor(usb_dev, 0, &config) != 0)
623 if (libusb_get_device_descriptor (usb_dev, &desc) != LIBUSB_SUCCESS)
626 // Special case for Imaging Source cameras
627 if ((0x199e == desc.idVendor) && (0x8101 == desc.idProduct)) {
630 for (interface_idx = 0;
631 !got_interface && interface_idx < config->bNumInterfaces;
633 interface = &config->interface[interface_idx];
635 for (altsetting_idx = 0;
636 !got_interface && altsetting_idx < interface->num_altsetting;
638 if_desc = &interface->altsetting[altsetting_idx];
640 /* Video, Streaming */
641 if (if_desc->bInterfaceClass == 14
642 && if_desc->bInterfaceSubClass == 2) {
649 libusb_free_config_descriptor(config);
652 uvc_device_t *uvc_dev = malloc(sizeof(*uvc_dev));
655 uvc_dev->usb_dev = usb_dev;
656 uvc_ref_device(uvc_dev);
659 list_internal = realloc(list_internal,
660 (num_uvc_devices + 1) * sizeof(*list_internal));
662 list_internal[num_uvc_devices - 1] = uvc_dev;
663 list_internal[num_uvc_devices] = NULL;
665 UVC_DEBUG(" UVC: %d", dev_idx);
667 UVC_DEBUG("non-UVC: %d", dev_idx);
671 libusb_free_device_list(usb_dev_list, 1);
673 *list = list_internal;
675 UVC_EXIT(UVC_SUCCESS);
680 * @brief Frees a list of device structures created with uvc_get_device_list.
683 * @param list Device list to free
684 * @param unref_devices Decrement the reference counter for each device
685 * in the list, and destroy any entries that end up with zero references
687 void uvc_free_device_list(uvc_device_t **list, uint8_t unref_devices) {
694 while ((dev = list[dev_idx++]) != NULL ) {
695 uvc_unref_device(dev);
705 * @brief Get the uvc_device_t corresponding to an open device
708 * @note Unref the uvc_device_t when you're done with it
710 * @param devh Device handle to an open UVC device
712 uvc_device_t *uvc_get_device(uvc_device_handle_t *devh) {
713 uvc_ref_device(devh->dev);
718 * @brief Get the underlying libusb device handle for an open device
721 * This can be used to access other interfaces on the same device, e.g.
722 * a webcam microphone.
724 * @note The libusb device handle is only valid while the UVC device is open;
725 * it will be invalidated upon calling uvc_close.
727 * @param devh UVC device handle to an open device
729 libusb_device_handle *uvc_get_libusb_handle(uvc_device_handle_t *devh) {
730 return devh->usb_devh;
734 * @brief Get input terminal descriptors for the open device.
736 * @note Do not modify the returned structure.
737 * @note The returned structure is part of a linked list. Iterate through
738 * it by using the 'next' pointers.
740 * @param devh Device handle to an open UVC device
742 const uvc_input_terminal_t *uvc_get_input_terminals(uvc_device_handle_t *devh) {
743 return devh->info->ctrl_if.input_term_descs;
747 * @brief Get output terminal descriptors for the open device.
749 * @note Do not modify the returned structure.
750 * @note The returned structure is part of a linked list. Iterate through
751 * it by using the 'next' pointers.
753 * @param devh Device handle to an open UVC device
755 const uvc_output_terminal_t *uvc_get_output_terminals(uvc_device_handle_t *devh) {
756 return devh->info->ctrl_if.output_term_descs ;
760 * @brief Get processing unit descriptors for the open device.
762 * @note Do not modify the returned structure.
763 * @note The returned structure is part of a linked list. Iterate through
764 * it by using the 'next' pointers.
766 * @param devh Device handle to an open UVC device
768 const uvc_processing_unit_t *uvc_get_processing_units(uvc_device_handle_t *devh) {
769 return devh->info->ctrl_if.processing_unit_descs;
773 * @brief Get extension unit descriptors for the open device.
775 * @note Do not modify the returned structure.
776 * @note The returned structure is part of a linked list. Iterate through
777 * it by using the 'next' pointers.
779 * @param devh Device handle to an open UVC device
781 const uvc_extension_unit_t *uvc_get_extension_units(uvc_device_handle_t *devh) {
782 return devh->info->ctrl_if.extension_unit_descs;
786 * @brief Increment the reference count for a device
789 * @param dev Device to reference
791 void uvc_ref_device(uvc_device_t *dev) {
794 dev->ref++; // これ排他制御要るんちゃうかなぁ(。・_・。)
795 // LOGI("ref=%d", dev->ref);
796 libusb_ref_device(dev->usb_dev);
802 * @brief Decrement the reference count for a device
804 * @note If the count reaches zero, the device will be discarded
806 * @param dev Device to unreference
808 void uvc_unref_device(uvc_device_t *dev) {
811 libusb_unref_device(dev->usb_dev);
812 dev->ref--; // これ排他制御要るんちゃうかなぁ(。・_・。)
814 // LOGI("ref=%d", dev->ref);
824 * Claim a UVC interface, detaching the kernel driver if necessary.
827 * @param devh UVC device handle
828 * @param idx UVC interface index
830 uvc_error_t uvc_claim_if(uvc_device_handle_t *devh, int idx) {
834 #if !UVC_DETACH_ATTACH
835 // libusb automatically attach/detach kernel driver on supported platforms
836 UVC_DEBUG("claiming interface %d", idx);
837 ret = libusb_claim_interface(devh->usb_devh, idx);
839 /* Tell libusb to detach any active kernel drivers. libusb will keep track of whether
840 * it found a kernel driver for this interface. */
841 ret = libusb_detach_kernel_driver(devh->usb_devh, idx);
843 if LIKELY(!ret || ret == LIBUSB_ERROR_NOT_FOUND || ret == LIBUSB_ERROR_NOT_SUPPORTED) {
844 UVC_DEBUG("claiming interface %d", idx);
845 ret = libusb_claim_interface(devh->usb_devh, idx);
847 UVC_DEBUG("not claiming interface %d: unable to detach kernel driver (%s)",
848 idx, uvc_strerror(ret));
856 * Release a UVC interface.
859 * @param devh UVC device handle
860 * @param idx UVC interface index
862 uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx) {
866 UVC_DEBUG("releasing interface %d", idx);
867 /* libusb_release_interface *should* reset the alternate setting to the first available,
868 but sometimes (e.g. on Darwin) it doesn't. Thus, we do it explicitly here.
869 This is needed to de-initialize certain cameras. */
870 // XXX but resetting the alt setting here manytimes leads trouble
871 // on GT-N7100(international Galaxy Note2 at lease with Android4.4.2)
872 // so we add flag to avoid the issue
873 if (devh->reset_on_release_if)
874 libusb_set_interface_alt_setting(devh->usb_devh, idx, 0);
876 ret = libusb_release_interface(devh->usb_devh, idx);
878 #if !UVC_DETACH_ATTACH
879 // libusb automatically attach/detach kernel driver on supported platforms
880 // and nothing to do here
882 if (UVC_SUCCESS == ret) {
883 /* Reattach any kernel drivers that were disabled when we claimed this interface */
884 ret = libusb_attach_kernel_driver(devh->usb_devh, idx);
887 UVC_DEBUG("reattached kernel driver to interface %d", idx);
888 } else if (ret == LIBUSB_ERROR_NOT_FOUND || ret == LIBUSB_ERROR_NOT_SUPPORTED) {
889 ret = UVC_SUCCESS; /* NOT_FOUND and NOT_SUPPORTED are OK: nothing to do */
891 UVC_DEBUG("error reattaching kernel driver to interface %d: %s",
892 idx, uvc_strerror(ret));
901 * Find a device's VideoControl interface and process its descriptor
904 uvc_error_t uvc_scan_control(uvc_device_t *dev, uvc_device_info_t *info) {
905 const struct libusb_interface_descriptor *if_desc;
906 uvc_error_t parse_ret, ret;
908 const unsigned char *buffer;
909 size_t buffer_left, block_size;
916 if (LIKELY(info && info->config)) { // XXX add to avoid crash
917 MARK("bNumInterfaces=%d", info->config->bNumInterfaces);
918 for (interface_idx = 0; interface_idx < info->config->bNumInterfaces; ++interface_idx) {
919 if_desc = &info->config->interface[interface_idx].altsetting[0];
920 MARK("interface_idx=%d:bInterfaceClass=%02x,bInterfaceSubClass=%02x", interface_idx, if_desc->bInterfaceClass, if_desc->bInterfaceSubClass);
921 // select first found Video control
922 if (if_desc->bInterfaceClass == LIBUSB_CLASS_VIDEO/*14*/ && if_desc->bInterfaceSubClass == 1) // Video, Control
925 // Another TIS camera hack.
926 if (if_desc->bInterfaceClass == 255 && if_desc->bInterfaceSubClass == 1) {
927 uvc_device_descriptor_t* dev_desc;
928 int haveTISCamera = 0;
929 uvc_get_device_descriptor (dev, &dev_desc);
930 if (dev_desc->idVendor == 0x199e && dev_desc->idProduct == 0x8101) {
933 uvc_free_device_descriptor (dev_desc);
942 if (UNLIKELY(!if_desc)) {
943 UVC_EXIT(UVC_ERROR_INVALID_DEVICE);
944 LOGE("UVC_ERROR_INVALID_DEVICE");
945 return UVC_ERROR_INVALID_DEVICE;
948 info->ctrl_if.bInterfaceNumber = interface_idx;
949 if (if_desc->bNumEndpoints != 0) {
950 info->ctrl_if.bEndpointAddress = if_desc->endpoint[0].bEndpointAddress;
953 buffer = if_desc->extra;
954 buffer_left = if_desc->extra_length;
956 while (buffer_left >= 3) { // parseX needs to see buf[0,2] = length,type
957 block_size = buffer[0];
958 parse_ret = uvc_parse_vc(dev, info, buffer, block_size);
960 if (parse_ret != UVC_SUCCESS) {
965 buffer_left -= block_size;
966 buffer += block_size;
974 * @brief Parse a VideoControl header.
977 uvc_error_t uvc_parse_vc_header(uvc_device_t *dev, uvc_device_info_t *info,
978 const unsigned char *block, size_t block_size) {
980 uvc_error_t scan_ret, ret = UVC_SUCCESS;
986 uvc_version = (block[4] >> 4) * 1000 + (block[4] & 0x0f) * 100
987 + (block[3] >> 4) * 10 + (block[3] & 0x0f);
990 info->ctrl_if.bcdUVC = SW_TO_SHORT(&block[3]);
992 switch (info->ctrl_if.bcdUVC) {
996 case 0x0150: // XXX add to support UVC 1.5
999 UVC_EXIT(UVC_ERROR_NOT_SUPPORTED);
1000 return UVC_ERROR_NOT_SUPPORTED;
1003 for (i = 12; i < block_size; ++i) {
1004 scan_ret = uvc_scan_streaming(dev, info, block[i]);
1005 if (scan_ret != UVC_SUCCESS) {
1016 * @brief Parse a VideoControl input terminal.
1019 uvc_error_t uvc_parse_vc_input_terminal(uvc_device_t *dev,
1020 uvc_device_info_t *info, const unsigned char *block, size_t block_size) {
1021 uvc_input_terminal_t *term;
1026 /* only supporting camera-type input terminals */
1027 if (SW_TO_SHORT(&block[4]) != UVC_ITT_CAMERA) {
1028 UVC_EXIT(UVC_SUCCESS);
1032 term = calloc(1, sizeof(*term));
1034 term->bTerminalID = block[3];
1035 term->wTerminalType = SW_TO_SHORT(&block[4]);
1036 term->wObjectiveFocalLengthMin = SW_TO_SHORT(&block[8]);
1037 term->wObjectiveFocalLengthMax = SW_TO_SHORT(&block[10]);
1038 term->wOcularFocalLength = SW_TO_SHORT(&block[12]);
1039 term->request = (term->bTerminalID << 8) | info->ctrl_if.bInterfaceNumber;
1040 term->bmControls = 0; // XXX
1041 for (i = 14 + block[14]; i >= 15; i--)
1042 term->bmControls = block[i] + (term->bmControls << 8);
1044 DL_APPEND(info->ctrl_if.input_term_descs, term);
1046 UVC_EXIT(UVC_SUCCESS);
1051 * @brief Parse a output terminal.
1054 uvc_error_t uvc_parse_vc_output_terminal(uvc_device_t *dev,
1055 uvc_device_info_t *info, const unsigned char *block, size_t block_size) {
1056 uvc_output_terminal_t *term;
1061 /* only supporting display-type input terminals */
1062 if (SW_TO_SHORT(&block[4]) != UVC_OTT_DISPLAY) {
1063 UVC_EXIT(UVC_SUCCESS);
1067 term = calloc(1, sizeof(*term));
1069 term->bTerminalID = block[3];
1070 term->wTerminalType = SW_TO_SHORT(&block[4]);
1071 term->bAssocTerminal = block[6];
1072 term->bSourceID = block[7];
1073 term->iTerminal = block[8];
1074 term->request = (term->bTerminalID << 8) | info->ctrl_if.bInterfaceNumber; // XXX
1075 // TODO depending on the wTerminalType
1077 DL_APPEND(info->ctrl_if.output_term_descs, term);
1079 UVC_EXIT(UVC_SUCCESS);
1084 * @brief Parse a VideoControl processing unit.
1087 uvc_error_t uvc_parse_vc_processing_unit(uvc_device_t *dev,
1088 uvc_device_info_t *info, const unsigned char *block, size_t block_size) {
1089 uvc_processing_unit_t *unit;
1094 unit = calloc(1, sizeof(*unit));
1095 unit->bUnitID = block[3];
1096 unit->bSourceID = block[4];
1097 unit->request = (unit->bUnitID << 8) | info->ctrl_if.bInterfaceNumber; // XXX
1099 unit->bmControls = 0; // XXX
1100 for (i = 7 + block[7]; i >= 8; i--)
1101 unit->bmControls = block[i] + (unit->bmControls << 8);
1103 DL_APPEND(info->ctrl_if.processing_unit_descs, unit);
1105 UVC_EXIT(UVC_SUCCESS);
1110 * @brief Parse a VideoControl extension unit.
1113 uvc_error_t uvc_parse_vc_extension_unit(uvc_device_t *dev,
1114 uvc_device_info_t *info, const unsigned char *block, size_t block_size) {
1115 uvc_extension_unit_t *unit = calloc(1, sizeof(*unit));
1116 const uint8_t *start_of_controls;
1117 int size_of_controls, num_in_pins;
1122 unit->bUnitID = block[3];
1123 memcpy(unit->guidExtensionCode, &block[4], 16);
1125 num_in_pins = block[21];
1126 size_of_controls = block[22 + num_in_pins];
1127 start_of_controls = &block[23 + num_in_pins];
1128 unit->request = (unit->bUnitID << 8) | info->ctrl_if.bInterfaceNumber;
1130 unit->bmControls = 0; // XXX
1131 for (i = size_of_controls - 1; i >= 0; i--)
1132 unit->bmControls = start_of_controls[i] + (unit->bmControls << 8);
1134 DL_APPEND(info->ctrl_if.extension_unit_descs, unit);
1136 UVC_EXIT(UVC_SUCCESS);
1141 * Process a single VideoControl descriptor block
1144 uvc_error_t uvc_parse_vc(uvc_device_t *dev, uvc_device_info_t *info,
1145 const unsigned char *block, size_t block_size) {
1146 int descriptor_subtype;
1147 uvc_error_t ret = UVC_SUCCESS;
1151 if (block[1] != LIBUSB_DT_CS_INTERFACE/*36*/) { // not a CS_INTERFACE descriptor??
1152 UVC_EXIT(UVC_SUCCESS);
1153 return UVC_SUCCESS; // UVC_ERROR_INVALID_DEVICE;
1156 descriptor_subtype = block[2];
1158 switch (descriptor_subtype) {
1160 ret = uvc_parse_vc_header(dev, info, block, block_size);
1162 case UVC_VC_INPUT_TERMINAL:
1163 ret = uvc_parse_vc_input_terminal(dev, info, block, block_size);
1165 case UVC_VC_OUTPUT_TERMINAL:
1167 case UVC_VC_SELECTOR_UNIT:
1169 case UVC_VC_PROCESSING_UNIT:
1170 ret = uvc_parse_vc_processing_unit(dev, info, block, block_size);
1172 case UVC_VC_EXTENSION_UNIT:
1173 ret = uvc_parse_vc_extension_unit(dev, info, block, block_size);
1176 LOGW("UVC_ERROR_INVALID_DEVICE:descriptor_subtype=0x%02x", descriptor_subtype);
1177 ret = UVC_ERROR_INVALID_DEVICE;
1185 * Process a VideoStreaming interface
1188 uvc_error_t uvc_scan_streaming(uvc_device_t *dev, uvc_device_info_t *info,
1189 int interface_idx) {
1190 const struct libusb_interface_descriptor *if_desc;
1191 const unsigned char *buffer;
1192 size_t buffer_left, block_size;
1193 uvc_error_t ret, parse_ret;
1194 uvc_streaming_interface_t *stream_if;
1200 if_desc = &(info->config->interface[interface_idx].altsetting[0]);
1201 buffer = if_desc->extra;
1202 buffer_left = if_desc->extra_length;
1203 // XXX some device have it's format descriptions after the endpoint descriptor
1204 if (UNLIKELY(!buffer || !buffer_left)) {
1205 if (if_desc->bNumEndpoints && if_desc->endpoint) {
1206 // try to use extra data in endpoint[0]
1207 buffer = if_desc->endpoint[0].extra;
1208 buffer_left = if_desc->endpoint[0].extra_length;
1211 stream_if = calloc(1, sizeof(*stream_if));
1212 stream_if->parent = info;
1213 stream_if->bInterfaceNumber = if_desc->bInterfaceNumber;
1214 DL_APPEND(info->stream_ifs, stream_if);
1216 if (LIKELY(buffer_left >= 3)) {
1217 while (buffer_left >= 3) {
1218 block_size = buffer[0];
1219 // MARK("bDescriptorType=0x%02x", buffer[1]);
1220 parse_ret = uvc_parse_vs(dev, info, stream_if, buffer, block_size);
1222 if (parse_ret != UVC_SUCCESS) {
1227 buffer_left -= block_size;
1228 buffer += block_size;
1231 LOGW("This VideoStreaming interface has no extra data");
1239 * @brief Parse a VideoStreaming header block.
1242 uvc_error_t uvc_parse_vs_input_header(uvc_streaming_interface_t *stream_if,
1243 const unsigned char *block, size_t block_size) {
1246 stream_if->bEndpointAddress = block[6] & 0x8f;
1247 stream_if->bTerminalLink = block[8];
1248 stream_if->bmInfo = block[7]; // XXX
1249 stream_if->bStillCaptureMethod = block[9]; // XXX
1250 stream_if->bTriggerSupport = block[10]; // XXX
1251 stream_if->bTriggerUsage = block[11]; // XXX
1252 stream_if->bmaControls = NULL;
1253 const uint8_t n = block[12];
1255 const uint8_t p = (block_size - 13) / n;
1257 uint64_t *bmaControls = (uint64_t *)calloc(p, sizeof(uint64_t));
1258 stream_if->bmaControls = bmaControls;
1261 for (pp = 1; pp <= p; pp++) {
1262 bma = &block[12 + pp * n];
1263 for (nn = n - 1; nn >= 0; --nn) {
1264 *bmaControls = *bma-- + (*bmaControls << 8);
1270 UVC_EXIT(UVC_SUCCESS);
1275 * @brief Parse a VideoStreaming uncompressed format block.
1278 uvc_error_t uvc_parse_vs_format_uncompressed(
1279 uvc_streaming_interface_t *stream_if, const unsigned char *block,
1280 size_t block_size) {
1283 uvc_format_desc_t *format = calloc(1, sizeof(*format));
1285 format->parent = stream_if;
1286 format->bDescriptorSubtype = block[2];
1287 format->bFormatIndex = block[3];
1288 //format->bmCapabilities = block[4];
1289 //format->bmFlags = block[5];
1290 memcpy(format->guidFormat, &block[5], 16);
1291 format->bBitsPerPixel = block[21];
1292 format->bDefaultFrameIndex = block[22];
1293 format->bAspectRatioX = block[23];
1294 format->bAspectRatioY = block[24];
1295 format->bmInterlaceFlags = block[25];
1296 format->bCopyProtect = block[26];
1298 DL_APPEND(stream_if->format_descs, format);
1300 UVC_EXIT(UVC_SUCCESS);
1305 * @brief Parse a VideoStreaming frame format block.
1308 uvc_error_t uvc_parse_vs_frame_format(uvc_streaming_interface_t *stream_if,
1309 const unsigned char *block, size_t block_size) {
1312 uvc_format_desc_t *format = calloc(1, sizeof(*format));
1314 format->parent = stream_if;
1315 format->bDescriptorSubtype = block[2];
1316 format->bFormatIndex = block[3];
1317 format->bNumFrameDescriptors = block[4];
1318 memcpy(format->guidFormat, &block[5], 16);
1319 format->bBitsPerPixel = block[21];
1320 format->bDefaultFrameIndex = block[22];
1321 format->bAspectRatioX = block[23];
1322 format->bAspectRatioY = block[24];
1323 format->bmInterlaceFlags = block[25];
1324 format->bCopyProtect = block[26];
1325 format->bVariableSize = block[27];
1327 DL_APPEND(stream_if->format_descs, format);
1329 UVC_EXIT(UVC_SUCCESS);
1334 * @brief Parse a VideoStreaming MJPEG format block.
1337 uvc_error_t uvc_parse_vs_format_mjpeg(uvc_streaming_interface_t *stream_if,
1338 const unsigned char *block, size_t block_size) {
1341 uvc_format_desc_t *format = calloc(1, sizeof(*format));
1343 format->parent = stream_if;
1344 format->bDescriptorSubtype = block[2];
1345 format->bFormatIndex = block[3];
1346 memcpy(format->fourccFormat, "MJPG", 4);
1347 format->bmFlags = block[5];
1348 format->bBitsPerPixel = 0;
1349 format->bDefaultFrameIndex = block[6];
1350 format->bAspectRatioX = block[7];
1351 format->bAspectRatioY = block[8];
1352 format->bmInterlaceFlags = block[9];
1353 format->bCopyProtect = block[10];
1355 DL_APPEND(stream_if->format_descs, format);
1357 UVC_EXIT(UVC_SUCCESS);
1362 * @brief Parse a VideoStreaming uncompressed frame block.
1365 uvc_error_t uvc_parse_vs_frame_frame(uvc_streaming_interface_t *stream_if,
1366 const unsigned char *block,
1367 size_t block_size) {
1368 uvc_format_desc_t *format;
1369 uvc_frame_desc_t *frame;
1371 const unsigned char *p;
1376 format = stream_if->format_descs->prev;
1377 frame = calloc(1, sizeof(*frame));
1379 frame->parent = format;
1381 frame->bDescriptorSubtype = block[2];
1382 frame->bFrameIndex = block[3];
1383 frame->bmCapabilities = block[4];
1384 frame->wWidth = block[5] + (block[6] << 8);
1385 frame->wHeight = block[7] + (block[8] << 8);
1386 frame->dwMinBitRate = DW_TO_INT(&block[9]);
1387 frame->dwMaxBitRate = DW_TO_INT(&block[13]);
1388 frame->dwDefaultFrameInterval = DW_TO_INT(&block[17]);
1389 frame->bFrameIntervalType = block[21];
1390 frame->dwBytesPerLine = DW_TO_INT(&block[22]);
1392 if (block[21] == 0) {
1393 frame->dwMinFrameInterval = DW_TO_INT(&block[26]);
1394 frame->dwMaxFrameInterval = DW_TO_INT(&block[30]);
1395 frame->dwFrameIntervalStep = DW_TO_INT(&block[34]);
1397 frame->intervals = calloc(block[21] + 1, sizeof(frame->intervals[0]));
1400 for (i = 0; i < block[21]; ++i) {
1401 frame->intervals[i] = DW_TO_INT(p);
1404 frame->intervals[block[21]] = 0;
1407 DL_APPEND(format->frame_descs, frame);
1409 UVC_EXIT(UVC_SUCCESS);
1414 * @brief Parse a VideoStreaming uncompressed frame block.
1417 uvc_error_t uvc_parse_vs_frame_uncompressed(
1418 uvc_streaming_interface_t *stream_if, const unsigned char *block,
1419 size_t block_size) {
1420 uvc_format_desc_t *format;
1421 uvc_frame_desc_t *frame;
1426 const unsigned char *p;
1431 format = stream_if->format_descs->prev;
1432 frame = calloc(1, sizeof(*frame));
1434 frame->parent = format;
1436 frame_type = frame->bDescriptorSubtype = block[2];
1437 frame->bFrameIndex = block[3];
1438 frame->bmCapabilities = block[4];
1439 frame->wWidth = block[5] + (block[6] << 8);
1440 frame->wHeight = block[7] + (block[8] << 8);
1441 frame->dwMinBitRate = DW_TO_INT(&block[9]);
1442 frame->dwMaxBitRate = DW_TO_INT(&block[13]);
1443 frame->dwMaxVideoFrameBufferSize = DW_TO_INT(&block[17]);
1444 frame->dwDefaultFrameInterval = DW_TO_INT(&block[21]);
1445 n = frame->bFrameIntervalType = block[25];
1448 frame->dwMinFrameInterval = DW_TO_INT(&block[26]);
1449 frame->dwMaxFrameInterval = DW_TO_INT(&block[30]);
1450 frame->dwFrameIntervalStep = DW_TO_INT(&block[34]);
1452 frame->intervals = calloc(n + 1, sizeof(frame->intervals[0]));
1455 for (i = 0; i < n; ++i) {
1456 interval = DW_TO_INT(p);
1457 frame->intervals[i] = interval ? interval : 1;
1460 frame->intervals[n] = 0;
1462 frame->dwDefaultFrameInterval
1463 = MIN(frame->intervals[n-1],
1464 MAX(frame->intervals[0], frame->dwDefaultFrameInterval));
1467 if (frame_type == UVC_VS_FRAME_UNCOMPRESSED) {
1468 frame->dwMaxVideoFrameBufferSize
1469 = format->bBitsPerPixel * frame->wWidth * frame->wHeight / 8;
1473 DL_APPEND(format->frame_descs, frame);
1475 UVC_EXIT(UVC_SUCCESS);
1480 * Process a single VideoStreaming descriptor block
1483 uvc_error_t uvc_parse_vs(uvc_device_t *dev, uvc_device_info_t *info,
1484 uvc_streaming_interface_t *stream_if, const unsigned char *block,
1485 size_t block_size) {
1487 int descriptor_subtype;
1492 descriptor_subtype = block[2];
1493 // MARK("descriptor_subtype=0x%02x", descriptor_subtype);
1494 switch (descriptor_subtype) {
1495 case UVC_VS_INPUT_HEADER:
1496 ret = uvc_parse_vs_input_header(stream_if, block, block_size);
1498 // case UVC_VS_STILL_IMAGE_FRAME: // FIXME unsupported now
1500 case UVC_VS_FORMAT_UNCOMPRESSED:
1501 ret = uvc_parse_vs_format_uncompressed(stream_if, block, block_size);
1503 case UVC_VS_FORMAT_MJPEG:
1504 ret = uvc_parse_vs_format_mjpeg(stream_if, block, block_size);
1506 case UVC_VS_FRAME_UNCOMPRESSED:
1507 case UVC_VS_FRAME_MJPEG:
1508 ret = uvc_parse_vs_frame_uncompressed(stream_if, block, block_size);
1510 case UVC_VS_FORMAT_FRAME_BASED:
1511 ret = uvc_parse_vs_frame_format(stream_if, block, block_size );
1513 case UVC_VS_FRAME_FRAME_BASED:
1514 ret = uvc_parse_vs_frame_frame(stream_if, block, block_size );
1516 // case UVC_VS_COLORFORMAT: // FIXME unsupported now
1519 /** @todo handle JPEG and maybe still frames or even DV... */
1520 LOGV("unsupported descriptor_subtype(0x%02x)", descriptor_subtype);
1529 * @brief Free memory associated with a UVC device
1530 * @pre Streaming must be stopped, and threads must have died
1532 void uvc_free_devh(uvc_device_handle_t *devh) {
1535 pthread_mutex_destroy(&devh->status_mutex); // XXX saki
1537 uvc_free_device_info(devh->info);
1539 if (devh->status_xfer)
1540 libusb_free_transfer(devh->status_xfer);
1547 /** @brief Close a device
1551 * Ends any stream that's in progress.
1553 * The device handle and frame structures will be invalidated.
1555 void uvc_close(uvc_device_handle_t *devh) {
1559 uvc_context_t *ctx = devh->dev->ctx;
1562 uvc_stop_streaming(devh);
1564 uvc_release_if(devh, devh->info->ctrl_if.bInterfaceNumber);
1566 #if !UVC_DETACH_ATTACH
1567 /* disable automatic attach/detach kernel driver on supported platforms in libusb */
1568 libusb_set_auto_detach_kernel_driver(devh->usb_devh, 0);
1570 /* If we are managing the libusb context and this is the last open device,
1571 * then we need to cancel the handler thread. When we call libusb_close,
1572 * it'll cause a return from the thread's libusb_handle_events call, after
1573 * which the handler thread will check the flag we set and then exit. */
1574 if (ctx->own_usb_ctx && ctx->open_devices == devh && devh->next == NULL) {
1575 ctx->kill_handler_thread = 1;
1576 libusb_close(devh->usb_devh);
1577 pthread_join(ctx->handler_thread, NULL);
1579 libusb_close(devh->usb_devh);
1582 DL_DELETE(ctx->open_devices, devh);
1584 uvc_unref_device(devh->dev);
1586 uvc_free_devh(devh);
1591 uvc_error_t uvc_set_reset_altsetting(uvc_device_handle_t *devh, uint8_t reset_on_release_if) {
1592 if (UNLIKELY(!devh))
1593 RETURN(UVC_ERROR_INVALID_PARAM, uvc_error_t);
1594 devh->reset_on_release_if = reset_on_release_if;
1595 RETURN(UVC_SUCCESS, uvc_error_t);
1599 * @brief Get number of open devices
1601 size_t uvc_num_devices(uvc_context_t *ctx) {
1604 uvc_device_handle_t *devh;
1608 DL_FOREACH(ctx->open_devices, devh)
1613 UVC_EXIT((int) count);
1617 void uvc_process_control_status(uvc_device_handle_t *devh, unsigned char *data, int len) {
1618 enum uvc_status_class status_class;
1619 uint8_t originator = 0, selector = 0, event = 0;
1620 enum uvc_status_attribute attribute = UVC_STATUS_ATTRIBUTE_UNKNOWN;
1621 void *content = NULL;
1622 size_t content_len = 0;
1623 int found_entity = 0;
1624 struct uvc_input_terminal *input_terminal;
1625 struct uvc_processing_unit *processing_unit;
1630 UVC_DEBUG("Short read of VideoControl status update (%d bytes)", len);
1635 originator = data[1];
1639 if (originator == 0) {
1640 UVC_DEBUG("Unhandled update from VC interface");
1642 return; /* @todo VideoControl virtual entity interface updates */
1646 UVC_DEBUG("Unhandled VC event %d", (int) event);
1651 /* printf("bSelector: %d\n", selector); */
1653 DL_FOREACH(devh->info->ctrl_if.input_term_descs, input_terminal) {
1654 if (input_terminal->bTerminalID == originator) {
1655 status_class = UVC_STATUS_CLASS_CONTROL_CAMERA;
1661 if (!found_entity) {
1662 DL_FOREACH(devh->info->ctrl_if.processing_unit_descs, processing_unit) {
1663 if (processing_unit->bUnitID == originator) {
1664 status_class = UVC_STATUS_CLASS_CONTROL_PROCESSING;
1671 if (!found_entity) {
1672 UVC_DEBUG("Got status update for unknown VideoControl entity %d",
1678 attribute = data[4];
1680 content_len = len - 5;
1682 UVC_DEBUG("Event: class=%d, event=%d, selector=%d, attribute=%d, content_len=%zd",
1683 status_class, event, selector, attribute, content_len);
1685 pthread_mutex_lock(&devh->status_mutex); // XXX saki
1687 if(devh->status_cb) {
1688 UVC_DEBUG("Running user-supplied status callback");
1689 devh->status_cb(status_class,
1693 content, content_len,
1694 devh->status_user_ptr);
1697 pthread_mutex_unlock(&devh->status_mutex); // XXX saki
1702 void uvc_process_streaming_status(uvc_device_handle_t *devh, unsigned char *data, int len) {
1707 UVC_DEBUG("Invalid streaming status event received.\n");
1714 UVC_DEBUG("Short read of status update (%d bytes)", len);
1718 UVC_DEBUG("Button (intf %u) %s len %d\n", data[1], data[3] ? "pressed" : "released", len);
1720 pthread_mutex_lock(&devh->status_mutex); // XXX saki
1722 if(devh->button_cb) {
1723 UVC_DEBUG("Running user-supplied button callback");
1724 devh->button_cb(data[1],
1726 devh->button_user_ptr);
1729 pthread_mutex_unlock(&devh->status_mutex); // XXX saki
1731 UVC_DEBUG("Stream %u error event %02x %02x len %d.\n", data[1], data[2], data[3], len);
1737 void uvc_process_status_xfer(uvc_device_handle_t *devh, struct libusb_transfer *transfer) {
1741 /* printf("Got transfer of aLen = %d\n", transfer->actual_length); */
1743 if (transfer->actual_length > 0) {
1744 switch (transfer->buffer[0] & 0x0f) {
1745 case 1: /* VideoControl interface */
1746 uvc_process_control_status(devh, transfer->buffer, transfer->actual_length);
1748 case 2: /* VideoStreaming interface */
1749 uvc_process_streaming_status(devh, transfer->buffer, transfer->actual_length);
1758 * @brief Process asynchronous status updates from the device.
1760 void _uvc_status_callback(struct libusb_transfer *transfer) {
1763 uvc_device_handle_t *devh = (uvc_device_handle_t *) transfer->user_data;
1765 switch (transfer->status) {
1766 case LIBUSB_TRANSFER_ERROR:
1767 case LIBUSB_TRANSFER_CANCELLED:
1768 case LIBUSB_TRANSFER_NO_DEVICE:
1769 UVC_DEBUG("not processing/resubmitting, status = %d", transfer->status);
1772 case LIBUSB_TRANSFER_COMPLETED:
1773 uvc_process_status_xfer(devh, transfer);
1775 case LIBUSB_TRANSFER_TIMED_OUT:
1776 case LIBUSB_TRANSFER_STALL:
1777 case LIBUSB_TRANSFER_OVERFLOW:
1778 UVC_DEBUG("retrying transfer, status = %d", transfer->status);
1782 uvc_error_t ret = libusb_submit_transfer(transfer);
1783 UVC_DEBUG("libusb_submit_transfer() = %d", ret);
1788 /** @brief Set a callback function to receive status updates
1792 void uvc_set_status_callback(uvc_device_handle_t *devh,
1793 uvc_status_callback_t cb, void *user_ptr) {
1796 pthread_mutex_lock(&devh->status_mutex); // XXX saki
1798 devh->status_cb = cb;
1799 devh->status_user_ptr = user_ptr;
1801 pthread_mutex_unlock(&devh->status_mutex); // XXX saki
1806 /** @brief Set a callback function to receive button events
1810 void uvc_set_button_callback(uvc_device_handle_t *devh,
1811 uvc_button_callback_t cb, void *user_ptr) {
1814 pthread_mutex_lock(&devh->status_mutex); // XXX saki
1816 devh->button_cb = cb;
1817 devh->button_user_ptr = user_ptr;
1819 pthread_mutex_unlock(&devh->status_mutex); // XXX saki
1825 * @brief Get format descriptions for the open device.
1827 * @note Do not modify the returned structure.
1829 * @param devh Device handle to an open UVC device
1831 const uvc_format_desc_t *uvc_get_format_descs(uvc_device_handle_t *devh) {
1832 return devh->info->stream_ifs->format_descs;