options to reset image settings to default

This commit is contained in:
Devaev Maxim
2020-02-19 08:04:50 +03:00
parent dfc98a67f2
commit 9353b3474a
3 changed files with 135 additions and 52 deletions

View File

@@ -77,9 +77,10 @@ static int _device_open_mmap(struct device_t *dev);
static int _device_open_queue_buffers(struct device_t *dev);
static void _device_open_alloc_picbufs(struct device_t *dev);
static int _device_apply_resolution(struct device_t *dev, unsigned width, unsigned height);
static void _device_apply_controls(struct device_t *dev);
static int _device_check_control(struct device_t *dev, const char *name, unsigned cid, int value, bool quiet);
static void _device_set_control(struct device_t *dev, const char *name, unsigned cid, int value, bool quiet);
static int _device_query_control(struct device_t *dev, struct v4l2_queryctrl *query, const char *name, unsigned cid, bool quiet);
static void _device_set_control(struct device_t *dev, struct v4l2_queryctrl *query, const char *name, unsigned cid, int value, bool quiet);
static const char *_format_to_string_fourcc(char *buf, size_t size, unsigned format);
static const char *_format_to_string_nullable(unsigned format);
@@ -610,65 +611,81 @@ static int _device_apply_resolution(struct device_t *dev, unsigned width, unsign
}
static void _device_apply_controls(struct device_t *dev) {
# define SET_CID(_cid, _dest, _value, _quiet) { \
if (_device_check_control(dev, #_dest, _cid, _value, _quiet) == 0) { \
_device_set_control(dev, #_dest, _cid, _value, _quiet); \
# define SET_CID_VALUE(_cid, _field, _value, _quiet) { \
struct v4l2_queryctrl query; \
if (_device_query_control(dev, &query, #_field, _cid, _quiet) == 0) { \
_device_set_control(dev, &query, #_field, _cid, _value, _quiet); \
} \
}
# define SET_CID_MANUAL(_cid, _dest) { \
if (dev->ctl._dest.value_set) { \
SET_CID(_cid, _dest, dev->ctl._dest.value, false); \
# define SET_CID_DEFAULT(_cid, _field, _quiet) { \
struct v4l2_queryctrl query; \
if (_device_query_control(dev, &query, #_field, _cid, _quiet) == 0) { \
_device_set_control(dev, &query, #_field, _cid, query.default_value, _quiet); \
} \
}
# define SET_CID_AUTO(_cid_auto, _cid_manual, _dest) { \
if (dev->ctl._dest.value_set || dev->ctl._dest.auto_set) { \
SET_CID(_cid_auto, _dest##_auto, dev->ctl._dest.auto_set, dev->ctl._dest.value_set); \
SET_CID_MANUAL(_cid_manual, _dest); \
# define CONTROL_MANUAL_CID(_cid, _field) { \
if (dev->ctl._field.value_set) { \
SET_CID_VALUE(_cid, _field, dev->ctl._field.value, false); \
} else if (dev->ctl._field.default_set) { \
SET_CID_DEFAULT(_cid, _field, false); \
} \
}
SET_CID_AUTO (V4L2_CID_AUTOBRIGHTNESS, V4L2_CID_BRIGHTNESS, brightness);
SET_CID_MANUAL ( V4L2_CID_CONTRAST, contrast);
SET_CID_MANUAL ( V4L2_CID_SATURATION, saturation);
SET_CID_AUTO (V4L2_CID_HUE_AUTO, V4L2_CID_HUE, hue);
SET_CID_MANUAL ( V4L2_CID_GAMMA, gamma);
SET_CID_MANUAL ( V4L2_CID_SHARPNESS, sharpness);
SET_CID_MANUAL ( V4L2_CID_BACKLIGHT_COMPENSATION, backlight_compensation);
SET_CID_AUTO (V4L2_CID_AUTO_WHITE_BALANCE, V4L2_CID_WHITE_BALANCE_TEMPERATURE, white_balance);
SET_CID_AUTO (V4L2_CID_AUTOGAIN, V4L2_CID_GAIN, gain);
# define CONTROL_AUTO_CID(_cid_auto, _cid_manual, _field) { \
if (dev->ctl._field.value_set) { \
SET_CID_VALUE(_cid_auto, _field##_auto, 0, true); \
SET_CID_VALUE(_cid_manual, _field, dev->ctl._field.value, false); \
} else if (dev->ctl._field.auto_set) { \
SET_CID_VALUE(_cid_auto, _field##_auto, 1, false); \
} else if (dev->ctl._field.default_set) { \
SET_CID_VALUE(_cid_auto, _field##_auto, 0, true); /* Reset inactive flag */ \
SET_CID_DEFAULT(_cid_manual, _field, false); \
SET_CID_DEFAULT(_cid_auto, _field##_auto, false); \
} \
}
# undef SET_CID_AUTO
# undef SET_CID_MANUAL
# undef SET_CID
CONTROL_AUTO_CID (V4L2_CID_AUTOBRIGHTNESS, V4L2_CID_BRIGHTNESS, brightness);
CONTROL_MANUAL_CID ( V4L2_CID_CONTRAST, contrast);
CONTROL_MANUAL_CID ( V4L2_CID_SATURATION, saturation);
CONTROL_AUTO_CID (V4L2_CID_HUE_AUTO, V4L2_CID_HUE, hue);
CONTROL_MANUAL_CID ( V4L2_CID_GAMMA, gamma);
CONTROL_MANUAL_CID ( V4L2_CID_SHARPNESS, sharpness);
CONTROL_MANUAL_CID ( V4L2_CID_BACKLIGHT_COMPENSATION, backlight_compensation);
CONTROL_AUTO_CID (V4L2_CID_AUTO_WHITE_BALANCE, V4L2_CID_WHITE_BALANCE_TEMPERATURE, white_balance);
CONTROL_AUTO_CID (V4L2_CID_AUTOGAIN, V4L2_CID_GAIN, gain);
# undef CONTROL_AUTO_CID
# undef CONTROL_MANUAL_CID
# undef SET_CID_DEFAULT
# undef SET_CID_VALUE
}
static int _device_check_control(struct device_t *dev, const char *name, unsigned cid, int value, bool quiet) {
struct v4l2_queryctrl query;
static int _device_query_control(struct device_t *dev, struct v4l2_queryctrl *query, const char *name, unsigned cid, bool quiet) {
MEMSET_ZERO(*query);
query->id = cid;
MEMSET_ZERO(query);
query.id = cid;
if (xioctl(dev->run->fd, VIDIOC_QUERYCTRL, &query) < 0 || query.flags & V4L2_CTRL_FLAG_DISABLED) {
if (xioctl(dev->run->fd, VIDIOC_QUERYCTRL, query) < 0 || query->flags & V4L2_CTRL_FLAG_DISABLED) {
if (!quiet) {
LOG_ERROR("Changing control %s is unsupported", name);
}
return -1;
}
if (value < query.minimum || value > query.maximum || value % query.step != 0) {
if (!quiet) {
LOG_ERROR("Invalid value %d of control %s: min=%d, max=%d, default=%d, step=%u",
value, name, query.minimum, query.maximum, query.default_value, query.step);
}
return -2;
}
return 0;
}
static void _device_set_control(struct device_t *dev, const char *name, unsigned cid, int value, bool quiet) {
static void _device_set_control(struct device_t *dev, struct v4l2_queryctrl *query, const char *name, unsigned cid, int value, bool quiet) {
struct v4l2_control ctl;
if (value < query->minimum || value > query->maximum || value % query->step != 0) {
if (!quiet) {
LOG_ERROR("Invalid value %d of control %s: min=%d, max=%d, default=%d, step=%u",
value, name, query->minimum, query->maximum, query->default_value, query->step);
}
return;
}
MEMSET_ZERO(ctl);
ctl.id = cid;
ctl.value = value;
@@ -678,7 +695,7 @@ static void _device_set_control(struct device_t *dev, const char *name, unsigned
LOG_PERROR("Can't set control %s", name);
}
} else if (!quiet) {
LOG_INFO("Using control %s: %d", name, ctl.value);
LOG_INFO("Applying control %s: %d", name, ctl.value);
}
}

View File

@@ -68,6 +68,7 @@ struct control_t {
int value;
bool value_set;
bool auto_set;
bool default_set;
};
struct controls_t {

View File

@@ -80,19 +80,29 @@ enum _OPT_VALUES {
_O_DEVICE_TIMEOUT = 10000,
_O_DEVICE_ERROR_DELAY,
_O_IMAGE_DEFAULT,
_O_BRIGHTNESS,
_O_BRIGHTNESS_AUTO,
_O_BRIGHTNESS_DEFAULT,
_O_CONTRAST,
_O_CONTRAST_DEFAULT,
_O_SATURATION,
_O_SATURATION_DEFAULT,
_O_HUE,
_O_HUE_AUTO,
_O_HUE_DEFAULT,
_O_GAMMA,
_O_GAMMA_DEFAULT,
_O_SHARPNESS,
_O_SHARPNESS_DEFAULT,
_O_BACKLIGHT_COMPENSATION,
_O_BACKLIGHT_COMPENSATION_DEFAULT,
_O_WHITE_BALANCE,
_O_WHITE_BALANCE_AUTO,
_O_WHITE_BALANCE_DEFAULT,
_O_GAIN,
_O_GAIN_AUTO,
_O_GAIN_DEFAULT,
_O_USER,
_O_PASSWD,
@@ -143,19 +153,29 @@ static const struct option _LONG_OPTS[] = {
{"device-timeout", required_argument, NULL, _O_DEVICE_TIMEOUT},
{"device-error-delay", required_argument, NULL, _O_DEVICE_ERROR_DELAY},
{"image-default", no_argument, NULL, _O_IMAGE_DEFAULT},
{"brightness", required_argument, NULL, _O_BRIGHTNESS},
{"brightness-auto", no_argument, NULL, _O_BRIGHTNESS_AUTO},
{"brightness-default", no_argument, NULL, _O_BRIGHTNESS_DEFAULT},
{"contrast", required_argument, NULL, _O_CONTRAST},
{"contrast-default", no_argument, NULL, _O_CONTRAST_DEFAULT},
{"saturation", required_argument, NULL, _O_SATURATION},
{"saturation-default", no_argument, NULL, _O_SATURATION_DEFAULT},
{"hue", required_argument, NULL, _O_HUE},
{"hue-auto", no_argument, NULL, _O_HUE_AUTO},
{"hue-default", no_argument, NULL, _O_HUE_DEFAULT},
{"gamma", required_argument, NULL, _O_GAMMA},
{"gamma-default", no_argument, NULL, _O_GAMMA_DEFAULT},
{"sharpness", required_argument, NULL, _O_SHARPNESS},
{"sharpness-default", no_argument, NULL, _O_SHARPNESS_DEFAULT},
{"backlight-compensation", required_argument, NULL, _O_BACKLIGHT_COMPENSATION},
{"backlight-compensation-default", no_argument, NULL, _O_BACKLIGHT_COMPENSATION_DEFAULT},
{"white-balance", required_argument, NULL, _O_WHITE_BALANCE},
{"white-balance-auto", no_argument, NULL, _O_WHITE_BALANCE_AUTO},
{"white-balance-default", no_argument, NULL, _O_WHITE_BALANCE_DEFAULT},
{"gain", required_argument, NULL, _O_GAIN},
{"gain-auto", no_argument, NULL, _O_GAIN_AUTO},
{"gain-default", no_argument, NULL, _O_GAIN_DEFAULT},
{"host", required_argument, NULL, _O_HOST},
{"port", required_argument, NULL, _O_PORT},
@@ -278,6 +298,7 @@ int options_parse(struct options_t *options, struct device_t *dev, struct encode
# define OPT_CTL(_dest) { \
dev->ctl._dest.value_set = true; \
dev->ctl._dest.auto_set = false; \
dev->ctl._dest.default_set = false; \
OPT_NUMBER("--"#_dest, dev->ctl._dest.value, INT_MIN, INT_MAX, 0); \
break; \
}
@@ -285,6 +306,18 @@ int options_parse(struct options_t *options, struct device_t *dev, struct encode
# define OPT_CTL_AUTO(_dest) { \
dev->ctl._dest.value_set = false; \
dev->ctl._dest.auto_set = true; \
dev->ctl._dest.default_set = false; \
break; \
}
# define OPT_CTL_DEFAULT_NOBREAK(_dest) { \
dev->ctl._dest.value_set = false; \
dev->ctl._dest.auto_set = false; \
dev->ctl._dest.default_set = true; \
}
# define OPT_CTL_DEFAULT(_dest) { \
OPT_CTL_DEFAULT_NOBREAK(_dest); \
break; \
}
@@ -335,19 +368,39 @@ int options_parse(struct options_t *options, struct device_t *dev, struct encode
case _O_DEVICE_TIMEOUT: OPT_NUMBER("--device-timeout", dev->timeout, 1, 60, 0);
case _O_DEVICE_ERROR_DELAY: OPT_NUMBER("--device-error-delay", dev->error_delay, 1, 60, 0);
case _O_IMAGE_DEFAULT:
OPT_CTL_DEFAULT_NOBREAK(brightness);
OPT_CTL_DEFAULT_NOBREAK(contrast);
OPT_CTL_DEFAULT_NOBREAK(saturation);
OPT_CTL_DEFAULT_NOBREAK(hue);
OPT_CTL_DEFAULT_NOBREAK(gamma);
OPT_CTL_DEFAULT_NOBREAK(sharpness);
OPT_CTL_DEFAULT_NOBREAK(backlight_compensation);
OPT_CTL_DEFAULT_NOBREAK(white_balance);
OPT_CTL_DEFAULT_NOBREAK(gain);
break;
case _O_BRIGHTNESS: OPT_CTL(brightness);
case _O_BRIGHTNESS_AUTO: OPT_CTL_AUTO(brightness);
case _O_BRIGHTNESS_DEFAULT: OPT_CTL_DEFAULT(brightness);
case _O_CONTRAST: OPT_CTL(contrast);
case _O_CONTRAST_DEFAULT: OPT_CTL_DEFAULT(contrast);
case _O_SATURATION: OPT_CTL(saturation);
case _O_SATURATION_DEFAULT: OPT_CTL_DEFAULT(saturation);
case _O_HUE: OPT_CTL(hue);
case _O_HUE_AUTO: OPT_CTL_AUTO(hue);
case _O_HUE_DEFAULT: OPT_CTL_DEFAULT(hue);
case _O_GAMMA: OPT_CTL(gamma);
case _O_GAMMA_DEFAULT: OPT_CTL_DEFAULT(gamma);
case _O_SHARPNESS: OPT_CTL(sharpness);
case _O_SHARPNESS_DEFAULT: OPT_CTL_DEFAULT(sharpness);
case _O_BACKLIGHT_COMPENSATION: OPT_CTL(backlight_compensation);
case _O_BACKLIGHT_COMPENSATION_DEFAULT: OPT_CTL_DEFAULT(backlight_compensation);
case _O_WHITE_BALANCE: OPT_CTL(white_balance);
case _O_WHITE_BALANCE_AUTO: OPT_CTL_AUTO(white_balance);
case _O_WHITE_BALANCE_DEFAULT: OPT_CTL_DEFAULT(white_balance);
case _O_GAIN: OPT_CTL(gain);
case _O_GAIN_AUTO: OPT_CTL_AUTO(gain);
case _O_GAIN_DEFAULT: OPT_CTL_DEFAULT(gain);
case _O_HOST: OPT_SET(server->host, optarg);
case _O_PORT: OPT_NUMBER("--port", server->port, 1, 65535, 0);
@@ -404,6 +457,8 @@ int options_parse(struct options_t *options, struct device_t *dev, struct encode
}
# endif
# undef OPT_CTL_DEFAULT
# undef OPT_CTL_DEFAULT_NOBREAK
# undef OPT_CTL_AUTO
# undef OPT_CTL
# undef OPT_PARSE
@@ -562,19 +617,29 @@ static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_s
printf(" after an error (timeout for example). Default: %u.\n\n", dev->error_delay);
printf("Image control options:\n");
printf("══════════════════════\n");
printf(" --brightness <N> ───────────── Set brightness. Default: no change.\n\n");
printf(" --brightness-auto ──────────── Enable automatic brightness control. Default: no change.\n\n");
printf(" --contrast <N> ─────────────── Set contrast. Default: no change.\n\n");
printf(" --saturation <N> ───────────── Set saturation. Default: no change.\n\n");
printf(" --hue <N> ─────────────────── Set hue. Default: no change.\n\n");
printf(" --hue-auto ─────────────────── Enable automatic hue control. Default: no change.\n\n");
printf(" --gamma <N> ───────────────── Set gamma. Default: no change.\n\n");
printf(" --sharpness <N> ───────────── Set sharpness. Default: no change.\n\n");
printf(" --backlight-compensation <N> ─ Set backlight compensation. Default: no change.\n\n");
printf(" --white-balance <N> ────────── Set white balance. Default: no change.\n\n");
printf(" --white-balance-auto ───────── Enable automatic white balance control. Default: no change.\n\n");
printf(" --gain <N> ─────────────────── Set gain. Default: no change.\n\n");
printf(" --gain-auto ────────────────── Enable automatic gain control. Default: no change.\n\n");
printf(" --image-default ────────────────── Reset all image settings bellow to default. Default: no change.\n\n");
printf(" --brightness <N> ───────────────── Set brightness. Default: no change.\n");
printf(" --brightness-auto ──────────────── Enable automatic brightness control. Default: no change.\n");
printf(" --brightness-default ───────────── Set default brightness. Default: no change.\n\n");
printf(" --contrast <N> ─────────────────── Set contrast. Default: no change.\n");
printf(" --contrast-default ─────────────── Set default contrast. Default: no change.\n\n");
printf(" --saturation <N> ───────────────── Set saturation. Default: no change.\n");
printf(" --saturation-default ───────────── Set default saturation. Default: no change.\n\n");
printf(" --hue <N> ──────────────────────── Set hue. Default: no change.\n");
printf(" --hue-auto ─────────────────────── Enable automatic hue control. Default: no change.\n");
printf(" --hue-default ──────────────────── Set default hue. Default: no change.\n\n");
printf(" --gamma <N> ────────────────────── Set gamma. Default: no change.\n");
printf(" --gamma-default ────────────────── Set default gamma. Default: no change.\n\n");
printf(" --sharpness <N> ────────────────── Set sharpness. Default: no change.\n");
printf(" --sharpness-default ────────────── Set default sharpness. Default: no change.\n\n");
printf(" --backlight-compensation <N> ───── Set backlight compensation. Default: no change.\n");
printf(" --backlight-compensation-default ─ Set default backlight compensation. Default: no change.\n\n");
printf(" --white-balance <N> ────────────── Set white balance. Default: no change.\n");
printf(" --white-balance-auto ───────────── Enable automatic white balance control. Default: no change.\n");
printf(" --white-balance-default ────────── Set default white balance. Default: no change.\n\n");
printf(" --gain <N> ─────────────────────── Set gain. Default: no change.\n");
printf(" --gain-auto ────────────────────── Enable automatic gain control. Default: no change.\n\n");
printf(" --gain-default ─────────────────── Set default gain. Default: no change.\n\n");
printf("HTTP server options:\n");
printf("════════════════════\n");
printf(" -s|--host <address> ──────── Listen on Hostname or IP. Default: %s.\n\n", server->host);