mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-28 20:56:33 +00:00
options to reset image settings to default
This commit is contained in:
95
src/device.c
95
src/device.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ struct control_t {
|
||||
int value;
|
||||
bool value_set;
|
||||
bool auto_set;
|
||||
bool default_set;
|
||||
};
|
||||
|
||||
struct controls_t {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user