Update uvc control query

This commit is contained in:
John Zhao 2018-04-09 22:24:34 +08:00
parent e061430e61
commit ef38681bd1
7 changed files with 154 additions and 60 deletions

View File

@ -6,6 +6,7 @@
#include <stdexcept> #include <stdexcept>
#include "device/device_s.h" #include "device/device_s.h"
#include "internal/channels.h"
#include "internal/config.h" #include "internal/config.h"
#include "internal/streams.h" #include "internal/streams.h"
#include "internal/strings.h" #include "internal/strings.h"
@ -19,7 +20,8 @@ Device::Device(const Model &model, std::shared_ptr<uvc::device> device)
motion_tracking_(false), motion_tracking_(false),
model_(model), model_(model),
device_(device), device_(device),
streams_(nullptr) { streams_(nullptr),
channels_(std::make_shared<Channels>(device)) {
VLOG(2) << __func__; VLOG(2) << __func__;
ReadDeviceInfo(); ReadDeviceInfo();
} }

View File

@ -23,6 +23,7 @@ struct device;
struct DeviceInfo; struct DeviceInfo;
class Channels;
class Streams; class Streams;
class Device { class Device {
@ -115,6 +116,8 @@ class Device {
std::mutex mtx_streams_; std::mutex mtx_streams_;
std::shared_ptr<Channels> channels_;
void ReadDeviceInfo(); void ReadDeviceInfo();
void WriteImgIntrinsics(const ImgIntrinsics &intrinsics); void WriteImgIntrinsics(const ImgIntrinsics &intrinsics);

View File

@ -2,8 +2,6 @@
#include <glog/logging.h> #include <glog/logging.h>
#include "uvc/uvc.h"
MYNTEYE_BEGIN_NAMESPACE MYNTEYE_BEGIN_NAMESPACE
Channels::Channels(std::shared_ptr<uvc::device> device) : device_(device) { Channels::Channels(std::shared_ptr<uvc::device> device) : device_(device) {
@ -14,31 +12,16 @@ Channels::~Channels() {
VLOG(2) << __func__; VLOG(2) << __func__;
} }
bool Channels::ControlQuery( bool Channels::XuControlQuery(
const uvc::xu &xu, uint8_t selector, const query_t &query, uint16_t size, uint8_t selector, uvc::xu_query query, uint16_t size, uint8_t *data) {
return XuControlQuery({3}, selector, query, size, data);
}
bool Channels::XuControlQuery(
const uvc::xu &xu, uint8_t selector, uvc::xu_query query, uint16_t size,
uint8_t *data) { uint8_t *data) {
CHECK_NOTNULL(device_); CHECK_NOTNULL(device_);
uvc::xu_query code; return uvc::xu_control_query(*device_, xu, selector, query, size, data);
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 MYNTEYE_END_NAMESPACE

View File

@ -2,9 +2,11 @@
#define MYNTEYE_INTERNAL_CHANNELS_H_ #define MYNTEYE_INTERNAL_CHANNELS_H_
#pragma once #pragma once
#include <map>
#include <memory> #include <memory>
#include "mynteye/mynteye.h" #include "mynteye/mynteye.h"
#include "uvc/uvc.h"
MYNTEYE_BEGIN_NAMESPACE MYNTEYE_BEGIN_NAMESPACE
@ -17,24 +19,34 @@ struct xu;
class Channels { class Channels {
public: public:
typedef enum Query { typedef enum Channel {
SET_CUR, CHANNEL_CAM_CTRL = 0x0100,
GET_CUR, CHANNEL_HALF_DUPLEX = 0x0200,
GET_MIN, CHANNEL_IMU_WRITE = 0x0300,
GET_MAX, CHANNEL_IMU_READ = 0x0400,
GET_DEF, CHANNEL_FILE = 0x0500,
LAST CHANNEL_LAST
} query_t; } channel_t;
typedef struct ControlInfo {
std::int32_t min;
std::int32_t max;
std::int32_t def;
} control_info_t;
explicit Channels(std::shared_ptr<uvc::device> device); explicit Channels(std::shared_ptr<uvc::device> device);
~Channels(); ~Channels();
private: private:
bool ControlQuery( bool XuControlQuery(
const uvc::xu &xu, uint8_t selector, const query_t &query, uint16_t size, uint8_t selector, uvc::xu_query query, uint16_t size, uint8_t *data);
bool XuControlQuery(
const uvc::xu &xu, uint8_t selector, uvc::xu_query query, uint16_t size,
uint8_t *data); uint8_t *data);
std::shared_ptr<uvc::device> device_; std::shared_ptr<uvc::device> device_;
std::map<Option, ControlInfo> control_infos_;
}; };
MYNTEYE_END_NAMESPACE MYNTEYE_END_NAMESPACE

View File

@ -109,6 +109,28 @@ std::string get_video_name(const device &device) {
return ""; return "";
} }
bool pu_control_range(
const device &device, Option option, int32_t *min, int32_t *max,
int32_t *def) {
// TODO(JohnZhao)
UNUSED(device)
UNUSED(option)
UNUSED(min)
UNUSED(max)
UNUSED(def)
return false;
}
bool pu_control_query(
const device &device, Option option, pu_query query, int32_t *value) {
// TODO(JohnZhao)
UNUSED(device)
UNUSED(option)
UNUSED(query)
UNUSED(value)
return false;
}
bool xu_control_query( bool xu_control_query(
const device &device, const xu &xu, uint8_t selector, xu_query query, const device &device, const xu &xu, uint8_t selector, xu_query query,
uint16_t size, uint8_t *data) { uint16_t size, uint8_t *data) {

View File

@ -192,12 +192,41 @@ struct device {
} }
} }
bool pu_control_range(
uint32_t id, int32_t *min, int32_t *max, int32_t *def) const {
struct v4l2_queryctrl query = {};
query.id = id;
if (xioctl(fd, VIDIOC_QUERYCTRL, &query) < 0) {
LOG_ERROR(WARNING, "pu_control_range failed");
return false;
}
if (min)
*min = query.minimum;
if (max)
*max = query.maximum;
if (def)
*def = query.default_value;
return true;
}
bool pu_control_query(uint32_t id, int query, int32_t *value) const {
CHECK_NOTNULL(value);
struct v4l2_control control = {id, *value};
if (xioctl(fd, query, &control) < 0) {
LOG_ERROR(WARNING, "pu_control_query failed");
return false;
}
*value = control.value;
return true;
}
bool xu_control_query( bool xu_control_query(
const xu &xu, uint8_t selector, uint8_t query, uint16_t size, const xu &xu, uint8_t selector, uint8_t query, uint16_t size,
uint8_t *data) const { uint8_t *data) const {
CHECK_NOTNULL(data);
uvc_xu_control_query q = {xu.unit, selector, query, size, data}; uvc_xu_control_query q = {xu.unit, selector, query, size, data};
if (xioctl(fd, UVCIOC_CTRL_QUERY, &q) < 0) { if (xioctl(fd, UVCIOC_CTRL_QUERY, &q) < 0) {
LOG_ERROR(WARNING, "UVCIOC_CTRL_QUERY failed"); LOG_ERROR(WARNING, "xu_control_query failed");
return false; return false;
} }
return true; return true;
@ -433,24 +462,60 @@ std::string get_video_name(const device &device) {
return device.dev_name; return device.dev_name;
} }
static uint32_t get_cid(Option option) {
switch (option) {
case Option::GAIN:
return V4L2_CID_GAIN;
case Option::BRIGHTNESS:
return V4L2_CID_BRIGHTNESS;
case Option::CONTRAST:
return V4L2_CID_CONTRAST;
default:
LOG(FATAL) << "No v4l2 cid for " << option;
}
}
bool pu_control_range(
const device &device, Option option, int32_t *min, int32_t *max,
int32_t *def) {
return device.pu_control_range(get_cid(option), min, max, def);
}
bool pu_control_query(
const device &device, Option option, pu_query query, int32_t *value) {
int code;
switch (query) {
case PU_QUERY_SET:
code = VIDIOC_S_CTRL;
break;
case PU_QUERY_GET:
code = VIDIOC_G_CTRL;
break;
default:
LOG(ERROR) << "pu_control_query request code is unaccepted";
return false;
}
return device.pu_control_query(get_cid(option), code, value);
}
bool xu_control_query( bool xu_control_query(
const device &device, const xu &xu, uint8_t selector, xu_query query, const device &device, const xu &xu, uint8_t selector, xu_query query,
uint16_t size, uint8_t *data) { uint16_t size, uint8_t *data) {
uint8_t code; uint8_t code;
switch (query) { switch (query) {
case XU_SET_CUR: case XU_QUERY_SET:
code = UVC_SET_CUR; code = UVC_SET_CUR;
break; break;
case XU_GET_CUR: case XU_QUERY_GET:
code = UVC_GET_CUR; code = UVC_GET_CUR;
break; break;
case XU_GET_MIN: case XU_QUERY_MIN:
code = UVC_GET_MIN; code = UVC_GET_MIN;
break; break;
case XU_GET_MAX: case XU_QUERY_MAX:
code = UVC_GET_MAX; code = UVC_GET_MAX;
break; break;
case XU_GET_DEF: case XU_QUERY_DEF:
code = UVC_GET_DEF; code = UVC_GET_DEF;
break; break;
default: default:

View File

@ -8,6 +8,7 @@
#include <vector> #include <vector>
#include "mynteye/mynteye.h" #include "mynteye/mynteye.h"
#include "mynteye/types.h"
#define MYNTEYE_VID 0x04B4 #define MYNTEYE_VID 0x04B4
#define MYNTEYE_PID 0x00F9 #define MYNTEYE_PID 0x00F9
@ -16,28 +17,24 @@ MYNTEYE_BEGIN_NAMESPACE
namespace uvc { namespace uvc {
/* typedef enum pu_query {
struct uvc_xu_control_query PU_QUERY_SET, // Set the value of a control
PU_QUERY_GET, // Get the value of a control
PU_QUERY_LAST
} pu_query;
__u8 unit Extension unit ID // Extension Unit
__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 { struct xu {
uint8_t unit = 3; uint8_t unit;
}; };
typedef enum xu_query { typedef enum xu_query {
XU_SET_CUR, // Set current value of the control XU_QUERY_SET, // Set current value of the control
XU_GET_CUR, // Get current value of the control XU_QUERY_GET, // Get current value of the control
XU_GET_MIN, // Get min value of the control XU_QUERY_MIN, // Get min value of the control
XU_GET_MAX, // Get max value of the control XU_QUERY_MAX, // Get max value of the control
XU_GET_DEF, // Get default value of the control XU_QUERY_DEF, // Get default value of the control
XU_LAST XU_QUERY_LAST
} xu_query; } xu_query;
struct context; // Opaque type representing access to the underlying UVC struct context; // Opaque type representing access to the underlying UVC
@ -56,7 +53,17 @@ int get_product_id(const device &device);
std::string get_video_name(const device &device); std::string get_video_name(const device &device);
// Access XU controls // Access PU (Processing Unit) controls
inline bool is_pu_control(Option option) {
return option >= Option::GAIN && option <= Option::CONTRAST;
}
bool pu_control_range(
const device &device, Option option, int32_t *min, int32_t *max,
int32_t *def);
bool pu_control_query(
const device &device, Option option, pu_query query, int32_t *value);
// Access XU (Extension Unit) controls
bool xu_control_query( bool xu_control_query(
const device &device, const xu &xu, uint8_t selector, xu_query query, const device &device, const xu &xu, uint8_t selector, xu_query query,
uint16_t size, uint8_t *data); uint16_t size, uint8_t *data);