template<class T> int get_pu(uvc_device_handle_t * devh, int subdevice, uint8_t unit, uint8_t control, int uvc_get_thing) { const int REQ_TYPE_GET = 0xa1; unsigned char buffer[4]; int status = libusb_control_transfer(devh->usb_devh, REQ_TYPE_GET, uvc_get_thing, control << 8, unit << 8 | (subdevice*2), buffer, sizeof(T), 0); if(status < 0) throw std::runtime_error(to_string() << "libusb_control_transfer(...) returned " << libusb_error_name(status)); if(status != sizeof(T)) throw std::runtime_error("insufficient data read from usb"); if(sizeof(T)==1) return buffer[0]; if(sizeof(T)==2) return SW_TO_SHORT(buffer); if(sizeof(T)==4) return DW_TO_INT(buffer); }
/** @ingroup ctrl * @brief Reads the WHITE_BALANCE_COMPONENT control. * @param devh UVC device handle * @param[out] blue TODO * @param[out] red TODO * @param req_code UVC_GET_* request to execute */ uvc_error_t uvc_get_white_balance_component(uvc_device_handle_t *devh, uint16_t* blue, uint16_t* red, enum uvc_req_code req_code) { uint8_t data[4]; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL << 8, 1 << 8, data, sizeof(data), 0); if (ret == sizeof(data)) { *blue = SW_TO_SHORT(data + 0); *red = SW_TO_SHORT(data + 2); return UVC_SUCCESS; } else { return ret; } }
/** @ingroup ctrl * @brief Reads the DIGITAL_WINDOW control. * @param devh UVC device handle * @param[out] window_top TODO * @param[out] window_left TODO * @param[out] window_bottom TODO * @param[out] window_right TODO * @param[out] num_steps TODO * @param[out] num_steps_units TODO * @param req_code UVC_GET_* request to execute */ uvc_error_t uvc_get_digital_window(uvc_device_handle_t *devh, uint16_t* window_top, uint16_t* window_left, uint16_t* window_bottom, uint16_t* window_right, uint16_t* num_steps, uint16_t* num_steps_units, enum uvc_req_code req_code) { uint8_t data[12]; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_CT_DIGITAL_WINDOW_CONTROL << 8, 1 << 8, data, sizeof(data), 0); if (ret == sizeof(data)) { *window_top = SW_TO_SHORT(data + 0); *window_left = SW_TO_SHORT(data + 2); *window_bottom = SW_TO_SHORT(data + 4); *window_right = SW_TO_SHORT(data + 6); *num_steps = SW_TO_SHORT(data + 8); *num_steps_units = SW_TO_SHORT(data + 10); return UVC_SUCCESS; } else { return ret; } }
/** * @brief Get the length of a control on a terminal or unit. * * @param devh UVC device handle * @param unit Unit or Terminal ID; obtain this from the uvc_extension_unit_t describing the extension unit * @param ctrl Vendor-specific control number to query * @return On success, the length of the control as reported by the device. Otherwise, * a uvc_error_t error describing the error encountered. * @ingroup ctrl */ int uvc_get_ctrl_len(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl) { unsigned char buf[2]; int ret = libusb_control_transfer(devh->usb_devh, REQ_TYPE_GET, UVC_GET_LEN, ctrl << 8, unit << 8, // FIXME this will work wrong, invalid wIndex value buf, 2, CTRL_TIMEOUT_MILLIS); if (UNLIKELY(ret < 0)) return ret; else return (unsigned short) SW_TO_SHORT(buf); }
/** @ingroup ctrl * @brief Reads the REGION_OF_INTEREST control. * @param devh UVC device handle * @param[out] roi_top TODO * @param[out] roi_left TODO * @param[out] roi_bottom TODO * @param[out] roi_right TODO * @param[out] auto_controls TODO * @param req_code UVC_GET_* request to execute */ uvc_error_t uvc_get_digital_roi(uvc_device_handle_t *devh, uint16_t* roi_top, uint16_t* roi_left, uint16_t* roi_bottom, uint16_t* roi_right, uint16_t* auto_controls, enum uvc_req_code req_code) { uint8_t data[10]; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_CT_REGION_OF_INTEREST_CONTROL << 8, 1 << 8, data, sizeof(data), 0); if (ret == sizeof(data)) { *roi_top = SW_TO_SHORT(data + 0); *roi_left = SW_TO_SHORT(data + 2); *roi_bottom = SW_TO_SHORT(data + 4); *roi_right = SW_TO_SHORT(data + 6); *auto_controls = SW_TO_SHORT(data + 8); return UVC_SUCCESS; } else { return ret; } }
/** * @brief Get the length of a control on a terminal or unit. * * @param devh UVC device handle * @param unit Unit or Terminal ID; obtain this from the uvc_extension_unit_t describing the extension unit * @param ctrl Vendor-specific control number to query * @return On success, the length of the control as reported by the device. Otherwise, * a uvc_error_t error describing the error encountered. * @ingroup ctrl */ int uvc_get_ctrl_len(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl) { unsigned char buf[2]; int ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, UVC_GET_LEN, ctrl << 8, unit << 8, buf, 2, 0 /* timeout */); if (ret < 0) return ret; else return (unsigned short)SW_TO_SHORT(buf); }
//---------------------------------------------------------------------- uvc_error_t uvc_get_zoom_abs(uvc_device_handle_t *devh, uint16_t *zoom, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer(devh->usb_devh, REQ_TYPE_GET, req_code, UVC_CT_ZOOM_ABSOLUTE_CONTROL << 8, devh->info->ctrl_if.input_term_descs->request, data, sizeof(data), CTRL_TIMEOUT_MILLIS); if (LIKELY(ret == sizeof(data))) { *zoom = SW_TO_SHORT(data); return UVC_SUCCESS; } else { return ret; } }
uvc_error_t uvc_get_digital_mult_limit(uvc_device_handle_t *devh, uint16_t *limit, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer(devh->usb_devh, REQ_TYPE_GET, req_code, UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL << 8, devh->info->ctrl_if.processing_unit_descs->request, data, sizeof(data), CTRL_TIMEOUT_MILLIS); if (LIKELY(ret == sizeof(data))) { *limit = SW_TO_SHORT(data); return UVC_SUCCESS; } else { return ret; } RETURN(-1, uvc_error_t); }
//---------------------------------------------------------------------- uvc_error_t uvc_get_iris_abs(uvc_device_handle_t *devh, uint16_t *iris, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer(devh->usb_devh, REQ_TYPE_GET, req_code, UVC_CT_FOCUS_ABSOLUTE_CONTROL << 8, // 1 << 8, /* = fixed ID(00) and wrong VideoControl interface descriptor subtype(UVC_VC_HEADER) on original libuvc */ devh->info->ctrl_if.input_term_descs->request, data, sizeof(data), CTRL_TIMEOUT_MILLIS); if (LIKELY(ret == sizeof(data))) { *iris = SW_TO_SHORT(data); return UVC_SUCCESS; } else { return ret; } }
uvc_error_t uvc_get_saturation(uvc_device_handle_t *devh, uint16_t *saturation, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer(devh->usb_devh, REQ_TYPE_GET, req_code, UVC_PU_SATURATION_CONTROL << 8, devh->info->ctrl_if.processing_unit_descs->request, data, sizeof(data), CTRL_TIMEOUT_MILLIS); if (LIKELY(ret == sizeof(data))) { *saturation = SW_TO_SHORT(data); return UVC_SUCCESS; } else { return ret; } RETURN(-1, uvc_error_t); }
uvc_error_t uvc_get_focus_abs(uvc_device_handle_t *devh, short *focus, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_CT_FOCUS_ABSOLUTE_CONTROL << 8, 1 << 8, data, sizeof(data), 0); if (ret == sizeof(data)) { *focus = SW_TO_SHORT(data); return UVC_SUCCESS; } else { return ret; } }
/** @ingroup ctrl * @brief Reads the ZOOM_ABSOLUTE control. * @param devh UVC device handle * @param[out] focal_length TODO * @param req_code UVC_GET_* request to execute */ uvc_error_t uvc_get_zoom_abs(uvc_device_handle_t *devh, uint16_t* focal_length, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_CT_ZOOM_ABSOLUTE_CONTROL << 8, 1 << 8, data, sizeof(data), 0); if (ret == sizeof(data)) { *focal_length = SW_TO_SHORT(data + 0); return UVC_SUCCESS; } else { return ret; } }
/** @ingroup ctrl * @brief Reads the DIGITAL_MULTIPLIER_LIMIT control. * @param devh UVC device handle * @param[out] multiplier_step TODO * @param req_code UVC_GET_* request to execute */ uvc_error_t uvc_get_digital_multiplier_limit(uvc_device_handle_t *devh, uint16_t* multiplier_step, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL << 8, 1 << 8, data, sizeof(data), 0); if (ret == sizeof(data)) { *multiplier_step = SW_TO_SHORT(data + 0); return UVC_SUCCESS; } else { return ret; } }
/** @ingroup ctrl * @brief Reads the WHITE_BALANCE_TEMPERATURE control. * @param devh UVC device handle * @param[out] temperature TODO * @param req_code UVC_GET_* request to execute */ uvc_error_t uvc_get_white_balance_temperature(uvc_device_handle_t *devh, uint16_t* temperature, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL << 8, 1 << 8, data, sizeof(data), 0); if (ret == sizeof(data)) { *temperature = SW_TO_SHORT(data + 0); return UVC_SUCCESS; } else { return ret; } }
/** @ingroup ctrl * @brief Reads the GAMMA control. * @param devh UVC device handle * @param[out] gamma TODO * @param req_code UVC_GET_* request to execute */ uvc_error_t uvc_get_gamma(uvc_device_handle_t *devh, uint16_t* gamma, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_PU_GAMMA_CONTROL << 8, 1 << 8, data, sizeof(data), 0); if (ret == sizeof(data)) { *gamma = SW_TO_SHORT(data + 0); return UVC_SUCCESS; } else { return ret; } }
/** @ingroup ctrl * @brief Reads the BRIGHTNESS control. * @param devh UVC device handle * @param[out] brightness TODO * @param req_code UVC_GET_* request to execute */ uvc_error_t uvc_get_brightness(uvc_device_handle_t *devh, int16_t* brightness, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_PU_BRIGHTNESS_CONTROL << 8, 1 << 8, data, sizeof(data), 0); if (ret == sizeof(data)) { *brightness = SW_TO_SHORT(data + 0); return UVC_SUCCESS; } else { return ret; } }
/** @ingroup ctrl * @brief Reads the BACKLIGHT_COMPENSATION control. * @param devh UVC device handle * @param[out] backlight_compensation device-dependent backlight compensation mode; zero means backlight compensation is disabled * @param req_code UVC_GET_* request to execute */ uvc_error_t uvc_get_backlight_compensation(uvc_device_handle_t *devh, uint16_t* backlight_compensation, enum uvc_req_code req_code) { uint8_t data[2]; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_PU_BACKLIGHT_COMPENSATION_CONTROL << 8, 1 << 8, data, sizeof(data), 0); if (ret == sizeof(data)) { *backlight_compensation = SW_TO_SHORT(data + 0); return UVC_SUCCESS; } else { return ret; } }