diff --git a/CMakeLists.txt b/CMakeLists.txt index 43b3800..2298fda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,6 +92,7 @@ endif() set(MYNTEYE_SRCS ${UVC_SRC} + src/internal/channels.cc src/internal/config.cc src/internal/streams.cc src/internal/strings.cc diff --git a/src/internal/channels.cc b/src/internal/channels.cc new file mode 100644 index 0000000..b386a48 --- /dev/null +++ b/src/internal/channels.cc @@ -0,0 +1,44 @@ +#include "internal/channels.h" + +#include + +#include "uvc/uvc.h" + +MYNTEYE_BEGIN_NAMESPACE + +Channels::Channels(std::shared_ptr device) : device_(device) { + VLOG(2) << __func__; +} + +Channels::~Channels() { + VLOG(2) << __func__; +} + +bool Channels::ControlQuery( + const uvc::xu &xu, uint8_t selector, const query_t &query, uint16_t size, + uint8_t *data) { + CHECK_NOTNULL(device_); + uvc::xu_query code; + switch (query) { + case SET_CUR: + code = uvc::XU_SET_CUR; + break; + case GET_CUR: + code = uvc::XU_GET_CUR; + break; + case GET_MIN: + code = uvc::XU_GET_MIN; + break; + case GET_MAX: + code = uvc::XU_GET_MAX; + break; + case GET_DEF: + code = uvc::XU_GET_DEF; + break; + default: + LOG(FATAL) << "ControlQuery query code is unaccepted"; + } + return uvc::xu_control_query(*device_, xu, selector, code, size, data); +} + +MYNTEYE_END_NAMESPACE diff --git a/src/internal/channels.h b/src/internal/channels.h new file mode 100644 index 0000000..37c7833 --- /dev/null +++ b/src/internal/channels.h @@ -0,0 +1,42 @@ +#ifndef MYNTEYE_INTERNAL_CHANNELS_H_ // NOLINT +#define MYNTEYE_INTERNAL_CHANNELS_H_ +#pragma once + +#include + +#include "mynteye/mynteye.h" + +MYNTEYE_BEGIN_NAMESPACE + +namespace uvc { + +struct device; +struct xu; + +} // namespace uvc + +class Channels { + public: + typedef enum Query { + SET_CUR, + GET_CUR, + GET_MIN, + GET_MAX, + GET_DEF, + LAST + } query_t; + + explicit Channels(std::shared_ptr device); + ~Channels(); + + private: + bool ControlQuery( + const uvc::xu &xu, uint8_t selector, const query_t &query, uint16_t size, + uint8_t *data); + + std::shared_ptr device_; +}; + +MYNTEYE_END_NAMESPACE + +#endif // MYNTEYE_INTERNAL_CHANNELS_H_ NOLINT diff --git a/src/uvc/uvc-libuvc.cc b/src/uvc/uvc-libuvc.cc index b579f51..0e2caef 100644 --- a/src/uvc/uvc-libuvc.cc +++ b/src/uvc/uvc-libuvc.cc @@ -109,26 +109,17 @@ std::string get_video_name(const device &device) { return ""; } -void get_control( - const device &device, const extension_unit &xu, uint8_t ctrl, void *data, - int len) { +bool xu_control_query( + const device &device, const xu &xu, uint8_t selector, xu_query query, + uint16_t size, uint8_t *data) { // TODO(JohnZhao) UNUSED(device) UNUSED(xu) - UNUSED(ctrl) + UNUSED(selector) + UNUSED(query) + UNUSED(size) UNUSED(data) - UNUSED(len) -} - -void set_control( - const device &device, const extension_unit &xu, uint8_t ctrl, void *data, - int len) { - // TODO(JohnZhao) - UNUSED(device) - UNUSED(xu) - UNUSED(ctrl) - UNUSED(data) - UNUSED(len) + return false; } void set_device_mode( diff --git a/src/uvc/uvc-v4l2.cc b/src/uvc/uvc-v4l2.cc index 31e3d4b..6bf07b7 100644 --- a/src/uvc/uvc-v4l2.cc +++ b/src/uvc/uvc-v4l2.cc @@ -192,26 +192,15 @@ struct device { } } - void get_control( - const extension_unit &xu, uint8_t control, void *data, - size_t size) const { - uvc_xu_control_query q = {static_cast(xu.unit), control, - UVC_GET_CUR, static_cast(size), - reinterpret_cast(data)}; + bool xu_control_query( + const xu &xu, uint8_t selector, uint8_t query, uint16_t size, + uint8_t *data) const { + uvc_xu_control_query q = {xu.unit, selector, query, size, data}; if (xioctl(fd, UVCIOC_CTRL_QUERY, &q) < 0) { - LOG_ERROR(FATAL, "UVCIOC_CTRL_QUERY:UVC_GET_CUR"); - } - } - - void set_control( - const extension_unit &xu, uint8_t control, void *data, - size_t size) const { - uvc_xu_control_query q = {static_cast(xu.unit), control, - UVC_SET_CUR, static_cast(size), - reinterpret_cast(data)}; - if (xioctl(fd, UVCIOC_CTRL_QUERY, &q) < 0) { - LOG_ERROR(FATAL, "UVCIOC_CTRL_QUERY:UVC_SET_CUR"); + LOG_ERROR(WARNING, "UVCIOC_CTRL_QUERY failed"); + return false; } + return true; } void set_format( @@ -444,16 +433,31 @@ std::string get_video_name(const device &device) { return device.dev_name; } -void get_control( - const device &device, const extension_unit &xu, uint8_t ctrl, void *data, - int len) { - device.get_control(xu, ctrl, data, len); -} - -void set_control( - const device &device, const extension_unit &xu, uint8_t ctrl, void *data, - int len) { - device.set_control(xu, ctrl, data, len); +bool xu_control_query( + const device &device, const xu &xu, uint8_t selector, xu_query query, + uint16_t size, uint8_t *data) { + uint8_t code; + switch (query) { + case XU_SET_CUR: + code = UVC_SET_CUR; + break; + case XU_GET_CUR: + code = UVC_GET_CUR; + break; + case XU_GET_MIN: + code = UVC_GET_MIN; + break; + case XU_GET_MAX: + code = UVC_GET_MAX; + break; + case XU_GET_DEF: + code = UVC_GET_DEF; + break; + default: + LOG(ERROR) << "xu_control_query request code is unaccepted"; + return false; + } + return device.xu_control_query(xu, selector, code, size, data); } void set_device_mode( diff --git a/src/uvc/uvc.h b/src/uvc/uvc.h index 6235db6..68c6942 100644 --- a/src/uvc/uvc.h +++ b/src/uvc/uvc.h @@ -16,10 +16,30 @@ MYNTEYE_BEGIN_NAMESPACE namespace uvc { -struct extension_unit { - int unit; +/* +struct uvc_xu_control_query + +__u8 unit Extension unit ID +__u8 selector Control selector +__u8 query Request code to send to the device +__u16 size Control data size (in bytes) +__u8 *data Control value +*/ + +// extension unit +struct xu { + uint8_t unit = 3; }; +typedef enum xu_query { + XU_SET_CUR, // Set current value of the control + XU_GET_CUR, // Get current value of the control + XU_GET_MIN, // Get min value of the control + XU_GET_MAX, // Get max value of the control + XU_GET_DEF, // Get default value of the control + XU_LAST +} xu_query; + struct context; // Opaque type representing access to the underlying UVC // implementation struct device; // Opaque type representing access to a specific UVC device @@ -37,12 +57,9 @@ int get_product_id(const device &device); std::string get_video_name(const device &device); // Access XU controls -void get_control( - const device &device, const extension_unit &xu, uint8_t ctrl, void *data, - int len); -void set_control( - const device &device, const extension_unit &xu, uint8_t ctrl, void *data, - int len); +bool xu_control_query( + const device &device, const xu &xu, uint8_t selector, xu_query query, + uint16_t size, uint8_t *data); // Control streaming typedef std::function video_channel_callback;