51 uvc_device_info_t *info,
52 const unsigned char *block,
size_t block_size);
54 uvc_device_info_t *info,
55 const unsigned char *block,
58 uvc_device_info_t *info,
59 const unsigned char *block,
size_t block_size);
61 uvc_device_info_t *info,
62 const unsigned char *block,
65 uvc_device_info_t *info,
66 const unsigned char *block,
70 uvc_device_info_t *info,
73 uvc_device_info_t *info,
74 uvc_streaming_interface_t *stream_if,
75 const unsigned char *block,
size_t block_size);
77 const unsigned char *block,
80 const unsigned char *block,
83 const unsigned char *block,
86 const unsigned char *block,
89 const unsigned char *block,
92 const unsigned char *block,
109 if (usb_dev == devh->dev->usb_dev)
128 int vid,
int pid,
const char *sn) {
148 while (!found_dev && (test_dev = list[dev_idx++]) != NULL) {
181 return libusb_get_bus_number(dev->usb_dev);
188 return libusb_get_device_address(dev->usb_dev);
220 struct libusb_device_handle *usb_devh;
222 struct libusb_device_descriptor desc;
226 ret = libusb_open(dev->usb_dev, &usb_devh);
227 UVC_DEBUG(
"libusb_open() = %d", ret);
236 internal_devh = calloc(1,
sizeof(*internal_devh));
237 internal_devh->dev =
dev;
238 internal_devh->usb_devh = usb_devh;
245 UVC_DEBUG(
"claiming control interface %d", internal_devh->info->ctrl_if.bInterfaceNumber);
246 ret =
uvc_claim_if(internal_devh, internal_devh->info->ctrl_if.bInterfaceNumber);
250 libusb_get_device_descriptor(dev->usb_dev, &desc);
251 internal_devh->is_isight = (desc.idVendor == 0x05ac && desc.idProduct == 0x8501);
253 if (internal_devh->info->ctrl_if.bEndpointAddress) {
254 internal_devh->status_xfer = libusb_alloc_transfer(0);
255 if (!internal_devh->status_xfer) {
260 libusb_fill_interrupt_transfer(internal_devh->status_xfer,
262 internal_devh->info->ctrl_if.bEndpointAddress,
263 internal_devh->status_buf,
264 sizeof(internal_devh->status_buf),
268 ret = libusb_submit_transfer(internal_devh->status_xfer);
269 UVC_DEBUG(
"libusb_submit_transfer() = %d", ret);
272 UVC_DEBUG(
"device has a status interrupt endpoint, but unable to read from it",);
277 if (dev->ctx->own_usb_ctx && dev->ctx->open_devices == NULL) {
282 DL_APPEND(dev->ctx->open_devices, internal_devh);
283 *devh = internal_devh;
290 if ( internal_devh->info ) {
291 uvc_release_if(internal_devh, internal_devh->info->ctrl_if.bInterfaceNumber);
293 libusb_close(usb_devh);
313 uvc_device_info_t **info) {
329 uvc_device_info_t **info,
332 uvc_device_info_t *internal_info;
336 internal_info = calloc(1,
sizeof(*internal_info));
337 if (!internal_info) {
342 if (libusb_get_config_descriptor(dev->usb_dev,
344 &(internal_info->config)) != 0) {
350 if (camera_number*2 > internal_info->config->bNumInterfaces)
358 internal_info->camera_number = camera_number;
368 *info = internal_info;
386 uvc_streaming_interface_t *stream_if, *stream_if_tmp;
392 DL_FOREACH_SAFE(info->ctrl_if.input_term_descs, input_term, input_term_tmp) {
393 DL_DELETE(info->ctrl_if.input_term_descs, input_term);
397 DL_FOREACH_SAFE(info->ctrl_if.processing_unit_descs, proc_unit, proc_unit_tmp) {
398 DL_DELETE(info->ctrl_if.processing_unit_descs, proc_unit);
402 DL_FOREACH_SAFE(info->ctrl_if.extension_unit_descs, ext_unit, ext_unit_tmp) {
403 DL_DELETE(info->ctrl_if.extension_unit_descs, ext_unit);
417 DL_DELETE(stream_if->format_descs, format);
426 libusb_free_config_descriptor(info->config);
448 struct libusb_device_descriptor usb_desc;
449 struct libusb_device_handle *usb_devh;
454 ret = libusb_get_device_descriptor(dev->usb_dev, &usb_desc);
461 desc_internal = calloc(1,
sizeof(*desc_internal));
462 desc_internal->
idVendor = usb_desc.idVendor;
463 desc_internal->
idProduct = usb_desc.idProduct;
465 if (libusb_open(dev->usb_dev, &usb_devh) == 0) {
466 unsigned char buf[64];
468 int bytes = libusb_get_string_descriptor_ascii(
469 usb_devh, usb_desc.iSerialNumber, buf,
sizeof(buf));
472 desc_internal->
serialNumber = strdup((
const char*) buf);
474 bytes = libusb_get_string_descriptor_ascii(
475 usb_devh, usb_desc.iManufacturer, buf,
sizeof(buf));
478 desc_internal->
manufacturer = strdup((
const char*) buf);
480 bytes = libusb_get_string_descriptor_ascii(
481 usb_devh, usb_desc.iProduct, buf,
sizeof(buf));
484 desc_internal->
product = strdup((
const char*) buf);
486 libusb_close(usb_devh);
488 UVC_DEBUG(
"can't open device %04x:%04x, not fetching serial etc.",
489 usb_desc.idVendor, usb_desc.idProduct);
492 *desc = desc_internal;
536 struct libusb_device **usb_dev_list;
537 struct libusb_device *usb_dev;
545 struct libusb_device_handle *usb_devh;
546 struct libusb_config_descriptor *
config;
547 struct libusb_device_descriptor desc;
548 uint8_t got_interface;
552 const struct libusb_interface *interface;
556 const struct libusb_interface_descriptor *if_desc;
560 num_usb_devices = libusb_get_device_list(ctx->usb_ctx, &usb_dev_list);
562 if (num_usb_devices < 0) {
567 list_internal = malloc(
sizeof(*list_internal));
568 *list_internal = NULL;
573 while ((usb_dev = usb_dev_list[++dev_idx]) != NULL) {
577 if (libusb_get_config_descriptor(usb_dev, 0, &config) != 0)
580 if ( libusb_get_device_descriptor ( usb_dev, &desc ) != LIBUSB_SUCCESS )
584 if ( 0x199e == desc.idVendor && 0x8101 == desc.idProduct ) {
588 for (interface_idx = 0;
589 !got_interface && interface_idx < config->bNumInterfaces;
591 interface = &config->interface[interface_idx];
593 for (altsetting_idx = 0;
594 !got_interface && altsetting_idx < interface->num_altsetting;
596 if_desc = &interface->altsetting[altsetting_idx];
599 if (if_desc->bInterfaceClass == 14 && if_desc->bInterfaceSubClass == 2) {
606 libusb_free_config_descriptor(config);
612 uvc_dev->usb_dev = usb_dev;
616 list_internal = realloc(list_internal, (num_uvc_devices + 1) *
sizeof(*list_internal));
618 list_internal[num_uvc_devices - 1] = uvc_dev;
619 list_internal[num_uvc_devices] = NULL;
621 UVC_DEBUG(
" UVC: %d", dev_idx);
623 UVC_DEBUG(
"non-UVC: %d", dev_idx);
627 libusb_free_device_list(usb_dev_list, 1);
629 *list = list_internal;
650 while ((dev = list[dev_idx++]) != NULL) {
686 return devh->usb_devh;
699 return devh->info->ctrl_if.input_term_descs;
725 return devh->info->ctrl_if.processing_unit_descs;
738 return devh->info->ctrl_if.extension_unit_descs;
751 libusb_ref_device(dev->usb_dev);
766 libusb_unref_device(dev->usb_dev);
789 ret = libusb_detach_kernel_driver(devh->usb_devh, idx);
791 if (ret ==
UVC_SUCCESS || ret == LIBUSB_ERROR_NOT_FOUND || ret == LIBUSB_ERROR_NOT_SUPPORTED) {
792 UVC_DEBUG(
"claiming interface %d", idx);
793 ret = libusb_claim_interface(devh->usb_devh, idx);
795 UVC_DEBUG(
"not claiming interface %d: unable to detach kernel driver (%s)",
814 UVC_DEBUG(
"releasing interface %d", idx);
818 libusb_set_interface_alt_setting(devh->usb_devh, idx, 0);
819 ret = libusb_release_interface(devh->usb_devh, idx);
823 ret = libusb_attach_kernel_driver(devh->usb_devh, idx);
826 UVC_DEBUG(
"reattached kernel driver to interface %d", idx);
827 }
else if (ret == LIBUSB_ERROR_NOT_FOUND || ret == LIBUSB_ERROR_NOT_SUPPORTED) {
830 UVC_DEBUG(
"error reattaching kernel driver to interface %d: %s",
844 const struct libusb_interface_descriptor *if_desc;
847 const unsigned char *
buffer;
848 size_t buffer_left, block_size;
857 for (interface_idx = info->camera_number*2; interface_idx < info->
config->bNumInterfaces; ++interface_idx) {
858 if_desc = &info->config->interface[interface_idx].altsetting[0];
860 if (if_desc->bInterfaceClass == 14 && if_desc->bInterfaceSubClass == 1)
864 if ( if_desc->bInterfaceClass == 255 && if_desc->bInterfaceSubClass == 1 ) {
866 int haveTISCamera = 0;
872 if ( haveTISCamera ) {
880 if (if_desc == NULL) {
885 info->ctrl_if.bInterfaceNumber = interface_idx;
886 if (if_desc->bNumEndpoints != 0) {
887 info->ctrl_if.bEndpointAddress = if_desc->endpoint[0].bEndpointAddress;
890 buffer = if_desc->extra;
891 buffer_left = if_desc->extra_length;
893 while (buffer_left >= 3) {
894 block_size = buffer[0];
895 parse_ret =
uvc_parse_vc(dev, info, buffer, block_size);
902 buffer_left -= block_size;
903 buffer += block_size;
915 uvc_device_info_t *info,
916 const unsigned char *block,
size_t block_size) {
928 info->ctrl_if.bcdUVC = SW_TO_SHORT(&block[3]);
930 switch (info->ctrl_if.bcdUVC) {
940 for (i = 12; i < block_size; ++i) {
957 uvc_device_info_t *info,
958 const unsigned char *block,
size_t block_size) {
970 term = calloc(1,
sizeof(*term));
978 for (i = 14 + block[14]; i >= 15; --i)
981 DL_APPEND(info->ctrl_if.input_term_descs, term);
992 uvc_device_info_t *info,
993 const unsigned char *block,
size_t block_size) {
999 unit = calloc(1,
sizeof(*unit));
1003 for (i = 7 + block[7]; i >= 8; --i)
1006 DL_APPEND(info->ctrl_if.processing_unit_descs, unit);
1017 uvc_device_info_t *info,
1018 const unsigned char *block,
size_t block_size) {
1020 const uint8_t *start_of_controls;
1021 int size_of_controls, num_in_pins;
1029 num_in_pins = block[21];
1030 size_of_controls = block[22 + num_in_pins];
1031 start_of_controls = &block[23 + num_in_pins];
1033 for (i = size_of_controls - 1; i >= 0; --i)
1036 DL_APPEND(info->ctrl_if.extension_unit_descs, unit);
1048 uvc_device_info_t *info,
1049 const unsigned char *block,
size_t block_size) {
1050 int descriptor_subtype;
1055 if (block[1] != 36) {
1060 descriptor_subtype = block[2];
1062 switch (descriptor_subtype) {
1066 case UVC_VC_INPUT_TERMINAL:
1069 case UVC_VC_OUTPUT_TERMINAL:
1071 case UVC_VC_SELECTOR_UNIT:
1073 case UVC_VC_PROCESSING_UNIT:
1076 case UVC_VC_EXTENSION_UNIT:
1092 uvc_device_info_t *info,
1093 int interface_idx) {
1094 const struct libusb_interface_descriptor *if_desc;
1095 const unsigned char *
buffer;
1096 size_t buffer_left, block_size;
1098 uvc_streaming_interface_t *stream_if;
1104 if_desc = &(info->config->interface[interface_idx].altsetting[0]);
1105 buffer = if_desc->extra;
1106 buffer_left = if_desc->extra_length;
1108 stream_if = calloc(1,
sizeof(*stream_if));
1109 stream_if->parent = info;
1110 stream_if->bInterfaceNumber = if_desc->bInterfaceNumber;
1113 while (buffer_left >= 3) {
1114 block_size = buffer[0];
1115 parse_ret =
uvc_parse_vs(dev, info, stream_if, buffer, block_size);
1122 buffer_left -= block_size;
1123 buffer += block_size;
1135 const unsigned char *block,
1136 size_t block_size) {
1139 stream_if->bEndpointAddress = block[6] & 0x8f;
1140 stream_if->bTerminalLink = block[8];
1151 const unsigned char *block,
1152 size_t block_size) {
1157 format->
parent = stream_if;
1170 DL_APPEND(stream_if->format_descs, format);
1181 const unsigned char *block,
1182 size_t block_size) {
1187 format->
parent = stream_if;
1200 DL_APPEND(stream_if->format_descs, format);
1211 const unsigned char *block,
1212 size_t block_size) {
1217 format->
parent = stream_if;
1229 DL_APPEND(stream_if->format_descs, format);
1240 const unsigned char *block,
1241 size_t block_size) {
1245 const unsigned char *
p;
1250 format = stream_if->format_descs->
prev;
1251 frame = calloc(1,
sizeof(*frame));
1258 frame->
wWidth = block[5] + (block[6] << 8);
1259 frame->
wHeight = block[7] + (block[8] << 8);
1266 if (block[21] == 0) {
1274 for (i = 0; i < block[21]; ++i) {
1292 const unsigned char *block,
1293 size_t block_size) {
1297 const unsigned char *
p;
1302 format = stream_if->format_descs->
prev;
1303 frame = calloc(1,
sizeof(*frame));
1310 frame->
wWidth = block[5] + (block[6] << 8);
1311 frame->
wHeight = block[7] + (block[8] << 8);
1318 if (block[25] == 0) {
1326 for (i = 0; i < block[25]; ++i) {
1345 uvc_device_info_t *info,
1346 uvc_streaming_interface_t *stream_if,
1347 const unsigned char *block,
size_t block_size) {
1349 int descriptor_subtype;
1354 descriptor_subtype = block[2];
1356 switch (descriptor_subtype) {
1378 UVC_DEBUG (
"unsupported descriptor subtype: %d\n", descriptor_subtype);
1396 if (devh->status_xfer)
1397 libusb_free_transfer(devh->status_xfer);
1425 if (ctx->own_usb_ctx && ctx->open_devices == devh && devh->next == NULL) {
1426 ctx->kill_handler_thread = 1;
1427 libusb_close(devh->usb_devh);
1428 pthread_join(ctx->handler_thread, NULL);
1430 libusb_close(devh->usb_devh);
1456 UVC_EXIT((
int) count);
1462 uint8_t originator = 0, selector = 0,
event = 0;
1465 size_t data_len = 0;
1471 if (transfer->actual_length < 4) {
1472 UVC_DEBUG(
"Short read of status update (%d bytes)", transfer->actual_length);
1477 originator = transfer->buffer[1];
1479 switch (transfer->buffer[0] & 0x0f) {
1481 int found_entity = 0;
1485 if (transfer->actual_length < 5) {
1486 UVC_DEBUG(
"Short read of VideoControl status update (%d bytes)",
1487 transfer->actual_length);
1492 event = transfer->buffer[2];
1493 selector = transfer->buffer[3];
1495 if (originator == 0) {
1496 UVC_DEBUG(
"Unhandled update from VC interface", );
1502 UVC_DEBUG(
"Unhandled VC event %d", (
int)
event);
1509 DL_FOREACH(devh->info->ctrl_if.input_term_descs, input_terminal) {
1517 if (!found_entity) {
1518 DL_FOREACH(devh->info->ctrl_if.processing_unit_descs, processing_unit) {
1519 if (processing_unit->
bUnitID == originator) {
1527 if (!found_entity) {
1528 UVC_DEBUG(
"Got status update for unknown VideoControl entity %d",
1534 attribute = transfer->buffer[4];
1535 data = transfer->buffer + 5;
1536 data_len = transfer->actual_length - 5;
1540 UVC_DEBUG(
"Unhandled update from VideoStreaming interface",);
1545 UVC_DEBUG(
"Event: class=%d, event=%d, selector=%d, attribute=%d, data_len=%zd",
1546 status_class,
event, selector, attribute, data_len);
1548 if(devh->status_cb) {
1549 UVC_DEBUG(
"Running user-supplied status callback",);
1550 devh->status_cb(status_class,
1555 devh->status_user_ptr);
1569 switch (transfer->status) {
1570 case LIBUSB_TRANSFER_ERROR:
1571 case LIBUSB_TRANSFER_CANCELLED:
1572 case LIBUSB_TRANSFER_NO_DEVICE:
1573 UVC_DEBUG(
"retrying transfer, status = %s", libusb_error_name(transfer->status));
1575 case LIBUSB_TRANSFER_COMPLETED:
1578 case LIBUSB_TRANSFER_TIMED_OUT:
1579 case LIBUSB_TRANSFER_STALL:
1580 case LIBUSB_TRANSFER_OVERFLOW:
1581 UVC_DEBUG(
"retrying transfer, status = %s", libusb_error_name(transfer->status));
1585 uvc_error_t ret = libusb_submit_transfer(transfer);
1586 UVC_DEBUG(
"libusb_submit_transfer() = %d", ret);
1600 devh->status_cb = cb;
1601 devh->status_user_ptr = user_ptr;
1615 return devh->info->stream_ifs->format_descs;
void uvc_ref_device(uvc_device_t *dev)
Increment the reference count for a device.
uvc_error_t uvc_parse_vs_frame_format(uvc_streaming_interface_t *stream_if, const unsigned char *block, size_t block_size)
uvc_error_t uvc_open(uvc_device_t *dev, uvc_device_handle_t **devh)
Open a UVC device, defaulting to the first interface found.
uvc_error_t uvc_find_device(uvc_context_t *ctx, uvc_device_t **dev, int vid, int pid, const char *sn)
Finds a camera identified by vendor, product and/or serial number.
uvc_error_t uvc_get_device_list(uvc_context_t *ctx, uvc_device_t ***list)
Get a list of the UVC devices attached to the system.
const uvc_input_terminal_t * uvc_get_input_terminals(uvc_device_handle_t *devh)
Get input terminal descriptors for the open device.
const uvc_format_desc_t * uvc_get_format_descs(uvc_device_handle_t *devh)
Get format descriptions for the open device.
enum uvc_error uvc_error_t
const char * manufacturer
#define DL_FOREACH(head, el)
void uvc_stop_streaming(uvc_device_handle_t *devh)
Stop streaming videoCloses all streams, ends threads and cancels pollers.
uint8_t guidExtensionCode[16]
uvc_device_t * uvc_get_device(uvc_device_handle_t *devh)
Get the uvc_device_t corresponding to an open device.
const char * serialNumber
GLenum GLuint GLenum GLsizei const GLchar * buf
struct uvc_device uvc_device_t
size_t uvc_num_devices(uvc_context_t *ctx)
uvc_error_t uvc_scan_streaming(uvc_device_t *dev, uvc_device_info_t *info, int interface_idx)
void uvc_free_device_list(uvc_device_t **list, uint8_t unref_devices)
Frees a list of device structures created with uvc_get_device_list.
void uvc_free_device_descriptor(uvc_device_descriptor_t *desc)
Frees a device descriptor created with uvc_get_device_descriptor.
uvc_error_t uvc_parse_vs_frame_frame(uvc_streaming_interface_t *stream_if, const unsigned char *block, size_t block_size)
void uvc_process_status_xfer(uvc_device_handle_t *devh, struct libusb_transfer *transfer)
void config(uvc::device &device, uint8_t gyro_bw, uint8_t gyro_range, uint8_t accel_bw, uint8_t accel_range, uint32_t time_seed)
uvc_error_t uvc_parse_vc_processing_unit(uvc_device_t *dev, uvc_device_info_t *info, const unsigned char *block, size_t block_size)
uint32_t dwFrameIntervalStep
struct uvc_format_desc * parent
uint32_t dwMaxVideoFrameBufferSize
void( uvc_status_callback_t)(enum uvc_status_class status_class, int event, int selector, enum uvc_status_attribute status_attribute, void *data, size_t data_len, void *user_ptr)
uvc_error_t uvc_parse_vc(uvc_device_t *dev, uvc_device_info_t *info, const unsigned char *block, size_t block_size)
uint8_t bFrameIntervalType
libusb_device_handle * uvc_get_libusb_handle(uvc_device_handle_t *devh)
Get the underlying libusb device handle for an open deviceThis can be used to access other interfaces...
enum uvc_vs_desc_subtype bDescriptorSubtype
const uvc_output_terminal_t * uvc_get_output_terminals(uvc_device_handle_t *devh)
Get output terminal descriptors for the open device.
uvc_error_t uvc_parse_vs_format_mjpeg(uvc_streaming_interface_t *stream_if, const unsigned char *block, size_t block_size)
uvc_error_t uvc_parse_vs_frame_uncompressed(uvc_streaming_interface_t *stream_if, const unsigned char *block, size_t block_size)
GLuint GLuint GLsizei count
void uvc_unref_device(uvc_device_t *dev)
Decrement the reference count for a device device.
void uvc_free_device_info(uvc_device_info_t *info)
#define DL_DELETE(head, del)
uvc_error_t uvc_get_device_info2(uvc_device_t *dev, uvc_device_info_t **info, int camera_number)
const uvc_extension_unit_t * uvc_get_extension_units(uvc_device_handle_t *devh)
Get extension unit descriptors for the open device.
uvc_error_t uvc_claim_if(uvc_device_handle_t *devh, int idx)
void LIBUSB_CALL _uvc_status_callback(struct libusb_transfer *transfer)
format
Formats: defines how each stream can be encoded. rs_format specifies how a frame is represented in me...
uvc_error_t uvc_parse_vc_header(uvc_device_t *dev, uvc_device_info_t *info, const unsigned char *block, size_t block_size)
Implementation-specific UVC constants and structures.
const char * uvc_strerror(uvc_error_t err)
Return a string explaining an error in the UVC driver.
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * data
uint8_t uvc_get_bus_number(uvc_device_t *dev)
Get the number of the bus to which the device is attached.
uvc_error_t uvc_parse_vs_format_uncompressed(uvc_streaming_interface_t *stream_if, const unsigned char *block, size_t block_size)
void uvc_set_status_callback(uvc_device_handle_t *devh, uvc_status_callback_t cb, void *user_ptr)
Set a callback function to receive status updates.
void uvc_close(uvc_device_handle_t *devh)
Close a device.
uvc_error_t uvc_parse_vc_input_terminal(uvc_device_t *dev, uvc_device_info_t *info, const unsigned char *block, size_t block_size)
void uvc_start_handler_thread(uvc_context_t *ctx)
uvc_error_t uvc_parse_vc_extension_unit(uvc_device_t *dev, uvc_device_info_t *info, const unsigned char *block, size_t block_size)
uvc_error_t uvc_open2(uvc_device_t *dev, uvc_device_handle_t **devh, int camera_number)
Open a UVC device, specifying the camera number, zero-based.
uint8_t uvc_get_device_address(uvc_device_t *dev)
Get the number assigned to the device within its bus.
struct uvc_context uvc_context_t
void uvc_free_devh(uvc_device_handle_t *devh)
int uvc_already_open(uvc_context_t *ctx, struct libusb_device *usb_dev)
const uvc_processing_unit_t * uvc_get_processing_units(uvc_device_handle_t *devh)
Get processing unit descriptors for the open device.
uvc_error_t uvc_get_device_descriptor(uvc_device_t *dev, uvc_device_descriptor_t **desc)
Get a descriptor that contains the general information about a deviceFree *desc with uvc_free_device_...
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define DL_APPEND(head, add)
uvc_error_t uvc_scan_control(uvc_device_t *dev, uvc_device_info_t *info)
uvc_error_t uvc_parse_vs(uvc_device_t *dev, uvc_device_info_t *info, uvc_streaming_interface_t *stream_if, const unsigned char *block, size_t block_size)
struct uvc_device_handle uvc_device_handle_t
#define DL_FOREACH_SAFE(head, el, tmp)
uint32_t dwMinFrameInterval
uvc_error_t uvc_get_device_info(uvc_device_t *dev, uvc_device_info_t **info)
uint32_t dwMaxFrameInterval
uint32_t dwDefaultFrameInterval
uvc_error_t uvc_parse_vs_input_header(uvc_streaming_interface_t *stream_if, const unsigned char *block, size_t block_size)
uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx)