Improve options handling
This commit is contained in:
parent
18be13ccc9
commit
1857cd8d77
@ -102,6 +102,7 @@ camera_options_t camera_options = {
|
|||||||
.auto_reconnect = 0,
|
.auto_reconnect = 0,
|
||||||
.auto_focus = true,
|
.auto_focus = true,
|
||||||
.options = "",
|
.options = "",
|
||||||
|
.list_options = false,
|
||||||
.h264 = {
|
.h264 = {
|
||||||
.options =
|
.options =
|
||||||
"video_bitrate_mode=0" OPTION_VALUE_LIST_SEP
|
"video_bitrate_mode=0" OPTION_VALUE_LIST_SEP
|
||||||
@ -153,30 +154,31 @@ option_value_t camera_type[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
option_t all_options[] = {
|
option_t all_options[] = {
|
||||||
DEFINE_OPTION_PTR(camera, path, string),
|
DEFINE_OPTION_PTR(camera, path, string, "Chooses the camera to use."),
|
||||||
DEFINE_OPTION(camera, width, uint),
|
DEFINE_OPTION(camera, width, uint, "Set the camera capture width."),
|
||||||
DEFINE_OPTION(camera, height, uint),
|
DEFINE_OPTION(camera, height, uint, "Set the camera capture height."),
|
||||||
DEFINE_OPTION_VALUES(camera, format, camera_formats),
|
DEFINE_OPTION_VALUES(camera, format, camera_formats, "Set the camera capture format."),
|
||||||
DEFINE_OPTION(camera, nbufs, uint),
|
DEFINE_OPTION(camera, nbufs, uint, "Set number of capture buffers. Preferred 2 or 3."),
|
||||||
DEFINE_OPTION_VALUES(camera, type, camera_type),
|
DEFINE_OPTION_VALUES(camera, type, camera_type, "Select camera capture."),
|
||||||
DEFINE_OPTION(camera, fps, uint),
|
DEFINE_OPTION(camera, fps, uint, "Set the desired capture framerate."),
|
||||||
DEFINE_OPTION_DEFAULT(camera, allow_dma, bool, "1"),
|
DEFINE_OPTION_DEFAULT(camera, allow_dma, bool, "1", "Prefer to use DMA access to reduce memory copy."),
|
||||||
DEFINE_OPTION(camera, high_res_factor, float),
|
DEFINE_OPTION(camera, high_res_factor, float, "Set the desired high resolution output scale factor."),
|
||||||
DEFINE_OPTION(camera, low_res_factor, float),
|
DEFINE_OPTION(camera, low_res_factor, float, "Set the desired low resolution output scale factor."),
|
||||||
DEFINE_OPTION_PTR(camera, options, list),
|
DEFINE_OPTION_PTR(camera, options, list, "Set the camera options. List all available options with `-camera-list_options`."),
|
||||||
DEFINE_OPTION(camera, auto_reconnect, uint),
|
DEFINE_OPTION(camera, auto_reconnect, uint, "Set the camera auto-reconnect delay in seconds."),
|
||||||
DEFINE_OPTION_DEFAULT(camera, auto_focus, bool, "1"),
|
DEFINE_OPTION_DEFAULT(camera, auto_focus, bool, "1", "Do auto-focus on start-up."),
|
||||||
|
|
||||||
DEFINE_OPTION_PTR(camera, isp.options, list),
|
DEFINE_OPTION_PTR(camera, isp.options, list, "Set the ISP processing options. List all available options with `-camera-list_options`."),
|
||||||
DEFINE_OPTION_PTR(camera, jpeg.options, list),
|
DEFINE_OPTION_PTR(camera, jpeg.options, list, "Set the JPEG compression options. List all available options with `-camera-list_options`."),
|
||||||
DEFINE_OPTION_PTR(camera, h264.options, list),
|
DEFINE_OPTION_PTR(camera, h264.options, list, "Set the H264 encoding options. List all available options with `-camera-list_options`."),
|
||||||
|
DEFINE_OPTION_DEFAULT(camera, list_options, bool, "1", "List all available options and exit."),
|
||||||
|
|
||||||
DEFINE_OPTION(http, port, uint),
|
DEFINE_OPTION(http, port, uint, "Set the HTTP web-server port."),
|
||||||
DEFINE_OPTION(http, maxcons, uint),
|
DEFINE_OPTION(http, maxcons, uint, "Set maximum number of concurrent HTTP connections."),
|
||||||
|
|
||||||
DEFINE_OPTION_DEFAULT(log, debug, bool, "1"),
|
DEFINE_OPTION_DEFAULT(log, debug, bool, "1", "Enable debug logging."),
|
||||||
DEFINE_OPTION_DEFAULT(log, verbose, bool, "1"),
|
DEFINE_OPTION_DEFAULT(log, verbose, bool, "1", "Enable verbose logging."),
|
||||||
DEFINE_OPTION_PTR(log, filter, list),
|
DEFINE_OPTION_PTR(log, filter, list, "Enable debug logging from the given files. Ex.: `-log-filter=buffer.cc`"),
|
||||||
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
@ -190,6 +192,18 @@ int main(int argc, char *argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (camera_options.list_options) {
|
||||||
|
camera = camera_open(&camera_options);
|
||||||
|
if (camera) {
|
||||||
|
printf("\n");
|
||||||
|
for (int i = 0; i < MAX_DEVICES; i++) {
|
||||||
|
device_dump_options(camera->devices[i], stdout);
|
||||||
|
}
|
||||||
|
camera_close(&camera);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
http_fd = http_server(&http_options, http_methods);
|
http_fd = http_server(&http_options, http_methods);
|
||||||
if (http_fd < 0) {
|
if (http_fd < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -26,6 +26,7 @@ typedef struct camera_options_s {
|
|||||||
unsigned auto_reconnect;
|
unsigned auto_reconnect;
|
||||||
|
|
||||||
char options[CAMERA_OPTIONS_LENGTH];
|
char options[CAMERA_OPTIONS_LENGTH];
|
||||||
|
bool list_options;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
char options[CAMERA_OPTIONS_LENGTH];
|
char options[CAMERA_OPTIONS_LENGTH];
|
||||||
|
70
opts/opts.c
70
opts/opts.c
@ -5,29 +5,75 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
static void print_help(option_t *options)
|
#define OPT_LENGTH 30
|
||||||
|
|
||||||
|
static void print_help(option_t *options, const char *cmd)
|
||||||
{
|
{
|
||||||
|
printf("Usage:\n");
|
||||||
|
printf("$ %s <options...>\n", cmd);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("Options:\n");
|
||||||
for (int i = 0; options[i].name; i++) {
|
for (int i = 0; options[i].name; i++) {
|
||||||
option_t *option = &options[i];
|
option_t *option = &options[i];
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
printf("%40s\t", option->name);
|
len += printf(" -%s", option->name);
|
||||||
|
if (option->default_value) {
|
||||||
|
len += printf("[=%s]", option->default_value);
|
||||||
|
} else if (option->value_mapping) {
|
||||||
|
len += printf("=arg");
|
||||||
|
} else {
|
||||||
|
len += printf("=%s", option->format);
|
||||||
|
}
|
||||||
|
if (len < OPT_LENGTH) {
|
||||||
|
printf("%*s", OPT_LENGTH-len, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("- %s", option->description);
|
||||||
|
if (option->value_mapping) {
|
||||||
|
printf(" Values: ");
|
||||||
|
for (int j = 0; option->value_mapping[j].name; j++) {
|
||||||
|
if (j > 0) printf(", ");
|
||||||
|
printf("%s", option->value_mapping[j].name);
|
||||||
|
}
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("Configuration:\n");
|
||||||
|
for (int i = 0; options[i].name; i++) {
|
||||||
|
option_t *option = &options[i];
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
if (option->value_list) {
|
if (option->value_list) {
|
||||||
char *string = option->value_list;
|
char *string = option->value_list;
|
||||||
char *token;
|
char *token;
|
||||||
int tokens = 0;
|
|
||||||
|
if (!*string)
|
||||||
|
continue;
|
||||||
|
|
||||||
while ((token = strsep(&string, OPTION_VALUE_LIST_SEP)) != NULL) {
|
while ((token = strsep(&string, OPTION_VALUE_LIST_SEP)) != NULL) {
|
||||||
if (tokens++ > 0)
|
len = printf(" -%s=", option->name);
|
||||||
printf("\n%40s\t", "");
|
if (len < OPT_LENGTH) {
|
||||||
printf("%s", token);
|
printf("%*s", OPT_LENGTH-len, " ");
|
||||||
|
}
|
||||||
|
printf("%s\n", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tokens)
|
|
||||||
printf("(none)");
|
|
||||||
} else if (option->value_string) {
|
} else if (option->value_string) {
|
||||||
|
len += printf(" -%s=", option->name);
|
||||||
|
if (len < OPT_LENGTH) {
|
||||||
|
printf("%*s", OPT_LENGTH-len, " ");
|
||||||
|
}
|
||||||
printf(option->format, option->value_string);
|
printf(option->format, option->value_string);
|
||||||
|
printf("\n");
|
||||||
} else {
|
} else {
|
||||||
|
len += printf(" -%s=", option->name);
|
||||||
|
if (len < OPT_LENGTH) {
|
||||||
|
printf("%*s", OPT_LENGTH-len, " ");
|
||||||
|
}
|
||||||
if (option->value_mapping) {
|
if (option->value_mapping) {
|
||||||
for (int j = 0; option->value_mapping[j].name; j++) {
|
for (int j = 0; option->value_mapping[j].name; j++) {
|
||||||
if (option->value_mapping[j].value == *option->value) {
|
if (option->value_mapping[j].value == *option->value) {
|
||||||
@ -39,10 +85,10 @@ static void print_help(option_t *options)
|
|||||||
|
|
||||||
unsigned mask = UINT_MAX >> ((sizeof(*option->value) - option->size) * 8);
|
unsigned mask = UINT_MAX >> ((sizeof(*option->value) - option->size) * 8);
|
||||||
printf(option->format, *option->value & mask);
|
printf(option->format, *option->value & mask);
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_opt(option_t *options, const char *key)
|
static int parse_opt(option_t *options, const char *key)
|
||||||
@ -116,7 +162,7 @@ int parse_opts(option_t *options, int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(key, "help")) {
|
if (!strcmp(key, "help")) {
|
||||||
print_help(options);
|
print_help(options, argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
opts/opts.h
13
opts/opts.h
@ -23,6 +23,7 @@ typedef struct options_s {
|
|||||||
option_value_t *value_mapping;
|
option_value_t *value_mapping;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
const char *default_value;
|
const char *default_value;
|
||||||
|
const char *description;
|
||||||
} option_t;
|
} option_t;
|
||||||
|
|
||||||
#define OPTION_VALUE_LIST_SEP ";"
|
#define OPTION_VALUE_LIST_SEP ";"
|
||||||
@ -34,38 +35,42 @@ typedef struct options_s {
|
|||||||
#define OPTION_FORMAT_string "%s"
|
#define OPTION_FORMAT_string "%s"
|
||||||
#define OPTION_FORMAT_list "%s"
|
#define OPTION_FORMAT_list "%s"
|
||||||
|
|
||||||
#define DEFINE_OPTION(_section, _name, _type) \
|
#define DEFINE_OPTION(_section, _name, _type, _desc) \
|
||||||
{ \
|
{ \
|
||||||
.name = #_section "-" #_name, \
|
.name = #_section "-" #_name, \
|
||||||
.value_##_type = &_section##_options._name, \
|
.value_##_type = &_section##_options._name, \
|
||||||
.format = OPTION_FORMAT_##_type, \
|
.format = OPTION_FORMAT_##_type, \
|
||||||
.size = sizeof(_section##_options._name), \
|
.size = sizeof(_section##_options._name), \
|
||||||
|
.description = _desc, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_OPTION_DEFAULT(_section, _name, _type, _default_value) \
|
#define DEFINE_OPTION_DEFAULT(_section, _name, _type, _default_value, _desc) \
|
||||||
{ \
|
{ \
|
||||||
.name = #_section "-" #_name, \
|
.name = #_section "-" #_name, \
|
||||||
.value_##_type = &_section##_options._name, \
|
.value_##_type = &_section##_options._name, \
|
||||||
.format = OPTION_FORMAT_##_type, \
|
.format = OPTION_FORMAT_##_type, \
|
||||||
.size = sizeof(_section##_options._name), \
|
.size = sizeof(_section##_options._name), \
|
||||||
.default_value = _default_value, \
|
.default_value = _default_value, \
|
||||||
|
.description = _desc, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_OPTION_VALUES(_section, _name, _value_mapping) \
|
#define DEFINE_OPTION_VALUES(_section, _name, _value_mapping, _desc) \
|
||||||
{ \
|
{ \
|
||||||
.name = #_section "-" #_name, \
|
.name = #_section "-" #_name, \
|
||||||
.value_hex = &_section##_options._name, \
|
.value_hex = &_section##_options._name, \
|
||||||
.format = OPTION_FORMAT_hex, \
|
.format = OPTION_FORMAT_hex, \
|
||||||
.value_mapping = _value_mapping, \
|
.value_mapping = _value_mapping, \
|
||||||
.size = sizeof(_section##_options._name), \
|
.size = sizeof(_section##_options._name), \
|
||||||
|
.description = _desc, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_OPTION_PTR(_section, _name, _type) \
|
#define DEFINE_OPTION_PTR(_section, _name, _type, _desc) \
|
||||||
{ \
|
{ \
|
||||||
.name = #_section "-" #_name, \
|
.name = #_section "-" #_name, \
|
||||||
.value_##_type = _section##_options._name, \
|
.value_##_type = _section##_options._name, \
|
||||||
.format = OPTION_FORMAT_##_type, \
|
.format = OPTION_FORMAT_##_type, \
|
||||||
.size = sizeof(_section##_options._name), \
|
.size = sizeof(_section##_options._name), \
|
||||||
|
.description = _desc, \
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_opts(option_t *options, int argc, char *argv[]);
|
int parse_opts(option_t *options, int argc, char *argv[]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user