mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-27 04:06:30 +00:00
First implementation of image settings
This commit is contained in:
45
src/device.c
45
src/device.c
@@ -65,6 +65,7 @@ static int _device_open_check_cap(struct device_t *dev);
|
||||
static int _device_open_dv_timings(struct device_t *dev);
|
||||
static int _device_apply_dv_timings(struct device_t *dev);
|
||||
static int _device_open_format(struct device_t *dev);
|
||||
static void _device_open_set_image_settings(struct device_t *dev);
|
||||
static void _device_open_alloc_picbufs(struct device_t *dev);
|
||||
static int _device_open_mmap(struct device_t *dev);
|
||||
static int _device_open_queue_buffers(struct device_t *dev);
|
||||
@@ -77,9 +78,12 @@ static const char *_standard_to_string(v4l2_std_id standard);
|
||||
|
||||
|
||||
struct device_t *device_init() {
|
||||
struct image_settings_t *img;
|
||||
struct device_runtime_t *run;
|
||||
struct device_t *dev;
|
||||
|
||||
A_CALLOC(img, 1);
|
||||
|
||||
A_CALLOC(run, 1);
|
||||
run->fd = -1;
|
||||
|
||||
@@ -93,12 +97,14 @@ struct device_t *device_init() {
|
||||
dev->n_workers = dev->n_buffers;
|
||||
dev->timeout = 1;
|
||||
dev->error_delay = 1;
|
||||
dev->img = img;
|
||||
dev->run = run;
|
||||
return dev;
|
||||
}
|
||||
|
||||
void device_destroy(struct device_t *dev) {
|
||||
free(dev->run);
|
||||
free(dev->img);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -136,6 +142,7 @@ int device_open(struct device_t *dev) {
|
||||
if (_device_open_format(dev) < 0) {
|
||||
goto error;
|
||||
}
|
||||
_device_open_set_image_settings(dev);
|
||||
if (_device_open_mmap(dev) < 0) {
|
||||
goto error;
|
||||
}
|
||||
@@ -350,6 +357,44 @@ static int _device_open_format(struct device_t *dev) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _device_open_set_image_settings(struct device_t *dev) {
|
||||
struct v4l2_queryctrl query;
|
||||
struct v4l2_control ctl;
|
||||
|
||||
# define SET_CID(_cid, _dest) { \
|
||||
MEMSET_ZERO(query); query.id = _cid; \
|
||||
if (xioctl(dev->run->fd, VIDIOC_QUERYCTRL, &query) != 0) { \
|
||||
LOG_INFO("Changing image " #_dest " is unsupported"); \
|
||||
} else { \
|
||||
MEMSET_ZERO(ctl); ctl.id = _cid; ctl.value = (int)dev->img->_dest; \
|
||||
if (xioctl(dev->run->fd, VIDIOC_S_CTRL, &ctl) < 0) { LOG_PERROR("Can't set image " #_dest); } \
|
||||
else { LOG_INFO("Using image " #_dest ": %d", ctl.value); } \
|
||||
} \
|
||||
}
|
||||
|
||||
# define SET_CID_MANUAL(_cid, _dest) { \
|
||||
if (dev->img->_dest##_set) { SET_CID(_cid, _dest); } \
|
||||
}
|
||||
|
||||
# define SET_CID_AUTO(_cid_auto, _cid_manual, _dest) { \
|
||||
if (dev->img->_dest##_set) { \
|
||||
SET_CID(_cid_auto, _dest##_auto); \
|
||||
if (!dev->img->_dest##_auto) { SET_CID(_cid_manual, _dest); } \
|
||||
} \
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
# undef SET_CID_AUTO
|
||||
# undef SET_CID_MANUAL
|
||||
# undef SET_CID
|
||||
}
|
||||
|
||||
static int _device_open_mmap(struct device_t *dev) {
|
||||
struct v4l2_requestbuffers req;
|
||||
|
||||
|
||||
17
src/device.h
17
src/device.h
@@ -69,6 +69,21 @@ struct device_runtime_t {
|
||||
bool capturing;
|
||||
};
|
||||
|
||||
#define S_MANUAL(_dest) int _dest; bool _dest##_set;
|
||||
#define S_AUTO(_dest) int _dest; bool _dest##_set; bool _dest##_auto;
|
||||
|
||||
struct image_settings_t {
|
||||
S_AUTO (brightness);
|
||||
S_MANUAL (contrast);
|
||||
S_MANUAL (saturation);
|
||||
S_AUTO (hue);
|
||||
S_MANUAL (gamma);
|
||||
S_MANUAL (sharpness);
|
||||
};
|
||||
|
||||
#undef S_AUTO
|
||||
#undef S_MANUAL
|
||||
|
||||
struct device_t {
|
||||
char *path;
|
||||
unsigned input;
|
||||
@@ -85,6 +100,8 @@ struct device_t {
|
||||
unsigned timeout;
|
||||
unsigned error_delay;
|
||||
|
||||
struct image_settings_t *img;
|
||||
|
||||
struct device_runtime_t *run;
|
||||
sig_atomic_t volatile stop;
|
||||
};
|
||||
|
||||
81
src/main.c
81
src/main.c
@@ -60,15 +60,24 @@ static const struct option _long_opts[] = {
|
||||
{"device-persistent", no_argument, NULL, 1001},
|
||||
{"device-error-delay", required_argument, NULL, 1002},
|
||||
|
||||
{"image-brightness", required_argument, NULL, 2000},
|
||||
{"image-brightness-auto", no_argument, NULL, 2001},
|
||||
{"image-contrast", required_argument, NULL, 2002},
|
||||
{"image-saturation", required_argument, NULL, 2003},
|
||||
{"image-hue", required_argument, NULL, 2004},
|
||||
{"image-hue-auto", no_argument, NULL, 2005},
|
||||
{"image-gamma", required_argument, NULL, 2006},
|
||||
{"image-sharpness", required_argument, NULL, 2007},
|
||||
|
||||
{"host", required_argument, NULL, 's'},
|
||||
{"port", required_argument, NULL, 'p'},
|
||||
{"unix", required_argument, NULL, 'u'},
|
||||
{"unix-rm", no_argument, NULL, 'r'},
|
||||
{"unix-mode", required_argument, NULL, 'o'},
|
||||
{"drop-same-frames", required_argument, NULL, 'e'},
|
||||
{"fake-width", required_argument, NULL, 2001},
|
||||
{"fake-height", required_argument, NULL, 2002},
|
||||
{"server-timeout", required_argument, NULL, 2003},
|
||||
{"fake-width", required_argument, NULL, 3001},
|
||||
{"fake-height", required_argument, NULL, 3002},
|
||||
{"server-timeout", required_argument, NULL, 3003},
|
||||
|
||||
{"perf", no_argument, NULL, 5000},
|
||||
{"verbose", no_argument, NULL, 5001},
|
||||
@@ -122,6 +131,16 @@ static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_s
|
||||
printf(" --device-persistent -- Don't re-initialize device on timeout. Default: disabled.\n\n");
|
||||
printf(" --device-error-delay <seconds> -- Delay before trying to connect to the device again\n");
|
||||
printf(" after a timeout. Default: %u\n\n", dev->error_delay);
|
||||
printf("Image options:\n");
|
||||
printf("---------------\n");
|
||||
printf(" --image-brightness <N> -- Set brightness. Default: no change.\n\n");
|
||||
printf(" --image-brightness-auto -- Enable automatic brightness control. Default: no change.\n\n");
|
||||
printf(" --image-contrast <N> -- Set contrast. Default: no change.\n\n");
|
||||
printf(" --image-saturation <N> -- Set saturation. Default: no change.\n\n");
|
||||
printf(" --image-hue <N> -- Set hue. Default: no change.\n\n");
|
||||
printf(" --image-hue-auto -- Enable automatic hue control. Default: no change.\n\n");
|
||||
printf(" --image-gamma <N> -- Set gamma. Default: no change.\n\n");
|
||||
printf(" --image-sharpness <N> -- Set sharpness. 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);
|
||||
@@ -152,22 +171,34 @@ static int _parse_options(int argc, char *argv[], struct device_t *dev, struct e
|
||||
# define OPT_SET(_dest, _value) \
|
||||
{ _dest = _value; break; }
|
||||
|
||||
# define OPT_UNSIGNED(_dest, _name, _min, _max) \
|
||||
{ errno = 0; char *_end = NULL; int _tmp = strtol(optarg, &_end, 0); \
|
||||
if (errno || *_end || _tmp < _min || _tmp > _max) \
|
||||
{ printf("Invalid value for '%s=%s'; min=%u; max=%u\n", _name, optarg, _min, _max); return -1; } \
|
||||
_dest = _tmp; break; }
|
||||
# define OPT_UNSIGNED(_dest, _name, _min, _max) { \
|
||||
errno = 0; char *_end = NULL; int _tmp = strtol(optarg, &_end, 0); \
|
||||
if (errno || *_end || _tmp < _min || _tmp > _max) { \
|
||||
printf("Invalid value for '%s=%s'; min=%u; max=%u\n", _name, optarg, _min, _max); \
|
||||
return -1; \
|
||||
} _dest = _tmp; break; }
|
||||
|
||||
# define OPT_PARSE(_dest, _func, _invalid, _name) \
|
||||
{ if ((_dest = _func(optarg)) == _invalid) \
|
||||
{ printf("Unknown " _name ": %s\n", optarg); return -1; } \
|
||||
break; }
|
||||
# define OPT_PARSE(_dest, _func, _invalid, _name) { \
|
||||
if ((_dest = _func(optarg)) == _invalid) { \
|
||||
printf("Unknown " _name ": %s\n", optarg); \
|
||||
return -1; \
|
||||
} break; }
|
||||
|
||||
# define OPT_INT(_dest, _name, _base) { \
|
||||
errno = 0; char *_end = NULL; int _tmp = strtol(optarg, &_end, _base); \
|
||||
if (errno || *_end) { \
|
||||
printf("Invalid value for '%s=%s'\n", _name, optarg); \
|
||||
return -1; \
|
||||
} _dest = _tmp; break; }
|
||||
|
||||
# define OPT_CHMOD(_dest, _name) \
|
||||
{ errno = 0; char *_end = NULL; int _tmp = strtol(optarg, &_end, 8); \
|
||||
if (errno || *_end) \
|
||||
{ printf("Invalid value for '%s=%s'\n", _name, optarg); return -1; } \
|
||||
_dest = _tmp; break; }
|
||||
OPT_INT(_dest, _name, 8)
|
||||
|
||||
# define OPT_IMG(_dest) \
|
||||
{ dev->img->_dest##_set = true; OPT_INT(dev->img->_dest, "--image-"#_dest, 10); break; }
|
||||
|
||||
# define OPT_IMG_AUTO(_dest) \
|
||||
{ dev->img->_dest##_set = true; dev->img->_dest##_auto = true; break; }
|
||||
|
||||
int index;
|
||||
int ch;
|
||||
@@ -195,15 +226,24 @@ static int _parse_options(int argc, char *argv[], struct device_t *dev, struct e
|
||||
case 1001: OPT_SET(dev->persistent, true);
|
||||
case 1002: OPT_UNSIGNED(dev->error_delay, "--device-error-delay", 1, 60);
|
||||
|
||||
case 2000: OPT_IMG(brightness);
|
||||
case 2001: OPT_IMG_AUTO(brightness);
|
||||
case 2002: OPT_IMG(contrast);
|
||||
case 2003: OPT_IMG(saturation);
|
||||
case 2004: OPT_IMG(hue);
|
||||
case 2005: OPT_IMG_AUTO(hue);
|
||||
case 2006: OPT_IMG(gamma);
|
||||
case 2007: OPT_IMG(sharpness);
|
||||
|
||||
case 's': OPT_SET(server->host, optarg);
|
||||
case 'p': OPT_UNSIGNED(server->port, "--port", 1, 65535);
|
||||
case 'u': OPT_SET(server->unix_path, optarg);
|
||||
case 'r': OPT_SET(server->unix_rm, true);
|
||||
case 'o': OPT_CHMOD(server->unix_mode, "--unix-mode");
|
||||
case 'e': OPT_UNSIGNED(server->drop_same_frames, "--drop-same-frames", 0, 30);
|
||||
case 2001: OPT_UNSIGNED(server->fake_width, "--fake-width", 0, 1920);
|
||||
case 2002: OPT_UNSIGNED(server->fake_height, "--fake-height", 0, 1200);
|
||||
case 2003: OPT_UNSIGNED(server->timeout, "--server-timeout", 1, 60);
|
||||
case 3001: OPT_UNSIGNED(server->fake_width, "--fake-width", 0, 1920);
|
||||
case 3002: OPT_UNSIGNED(server->fake_height, "--fake-height", 0, 1200);
|
||||
case 3003: OPT_UNSIGNED(server->timeout, "--server-timeout", 1, 60);
|
||||
|
||||
case 5000: OPT_SET(log_level, LOG_LEVEL_PERF);
|
||||
case 5001: OPT_SET(log_level, LOG_LEVEL_VERBOSE);
|
||||
@@ -216,7 +256,10 @@ static int _parse_options(int argc, char *argv[], struct device_t *dev, struct e
|
||||
}
|
||||
}
|
||||
|
||||
# undef OPT_IMG_AUTO
|
||||
# undef OPT_IMG
|
||||
# undef OPT_CHMOD
|
||||
# undef OPT_INT
|
||||
# undef OPT_PARSE
|
||||
# undef OPT_UNSIGNED
|
||||
# undef OPT_SET
|
||||
|
||||
Reference in New Issue
Block a user