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

View File

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

View File

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

View File

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

View File

@ -109,6 +109,28 @@ std::string get_video_name(const device &device) {
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(
const device &device, const xu &xu, uint8_t selector, xu_query query,
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(
const xu &xu, uint8_t selector, uint8_t query, uint16_t size,
uint8_t *data) const {
CHECK_NOTNULL(data);
uvc_xu_control_query q = {xu.unit, selector, query, size, data};
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 true;
@ -433,24 +462,60 @@ std::string get_video_name(const device &device) {
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(
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:
case XU_QUERY_SET:
code = UVC_SET_CUR;
break;
case XU_GET_CUR:
case XU_QUERY_GET:
code = UVC_GET_CUR;
break;
case XU_GET_MIN:
case XU_QUERY_MIN:
code = UVC_GET_MIN;
break;
case XU_GET_MAX:
case XU_QUERY_MAX:
code = UVC_GET_MAX;
break;
case XU_GET_DEF:
case XU_QUERY_DEF:
code = UVC_GET_DEF;
break;
default:

View File

@ -8,6 +8,7 @@
#include <vector>
#include "mynteye/mynteye.h"
#include "mynteye/types.h"
#define MYNTEYE_VID 0x04B4
#define MYNTEYE_PID 0x00F9
@ -16,28 +17,24 @@ MYNTEYE_BEGIN_NAMESPACE
namespace uvc {
/*
struct uvc_xu_control_query
typedef enum pu_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
__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
// Extension Unit
struct xu {
uint8_t unit = 3;
uint8_t unit;
};
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_SET, // Set current value of the control
XU_QUERY_GET, // Get current value of the control
XU_QUERY_MIN, // Get min value of the control
XU_QUERY_MAX, // Get max value of the control
XU_QUERY_DEF, // Get default value of the control
XU_QUERY_LAST
} xu_query;
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);
// 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(
const device &device, const xu &xu, uint8_t selector, xu_query query,
uint16_t size, uint8_t *data);