diff --git a/cmd/main.c b/cmd/main.c index 39d92b3..6bc407a 100644 --- a/cmd/main.c +++ b/cmd/main.c @@ -24,20 +24,28 @@ http_method_t http_methods[] = { camera_options_t camera_options = { .path = "/dev/video0", .width = 1920, - .height = 720, - .format = 0, + .height = 1080, + .format = V4L2_PIX_FMT_SRGGB10P, .nbufs = 4, .fps = 30, .allow_dma = true }; http_server_options_t http_options = { - .listen_port = 9092, + .port = 9092, .maxcons = 10 }; option_t all_options[] = { - DEFINE_OPTION(camera, width, "%d"), + DEFINE_OPTION_PTR(camera, path, "%s"), + DEFINE_OPTION(camera, width, uint), + DEFINE_OPTION(camera, height, uint), + DEFINE_OPTION(camera, format, uint), + DEFINE_OPTION(camera, nbufs, uint), + DEFINE_OPTION(camera, fps, uint), + DEFINE_OPTION(camera, allow_dma, bool), + DEFINE_OPTION(http, port, uint), + DEFINE_OPTION(http, maxcons, uint), {} }; @@ -48,6 +56,10 @@ int main(int argc, char *argv[]) int ret = -1; const char *env; + if (parse_opts(all_options, argc, argv) < 0) { + return -1; + } + if (env = getenv("DEBUG")) { log_debug = strstr(env, "1") ? 1 : 0; } @@ -55,13 +67,13 @@ int main(int argc, char *argv[]) camera_init(&camera); camera.options = camera_options; - //camera.width = 1920; camera.height = 1080; - strcpy(camera.options.path, "/dev/video2"); camera.options.width = 2328; camera.options.height = 1748; camera.options.format = V4L2_PIX_FMT_SRGGB10P; // 1164x874 - //camera.width = 4656; camera.height = 3496; - //camera.width = 3840; camera.height = 2160; - //camera.width = 1280; camera.height = 720; - strcpy(camera.options.path, "/dev/video0"); camera.options.width = 1920; camera.options.height = 1080; camera.options.format = V4L2_PIX_FMT_YUYV; camera.options.format = V4L2_PIX_FMT_MJPEG; camera.options.allow_dma = false; - camera.options.nbufs = 1; + // //camera.width = 1920; camera.height = 1080; + // strcpy(camera.options.path, "/dev/video2"); camera.options.width = 2328; camera.options.height = 1748; camera.options.format = V4L2_PIX_FMT_SRGGB10P; // 1164x874 + // //camera.width = 4656; camera.height = 3496; + // //camera.width = 3840; camera.height = 2160; + // //camera.width = 1280; camera.height = 720; + // strcpy(camera.options.path, "/dev/video0"); camera.options.width = 1920; camera.options.height = 1080; camera.options.format = V4L2_PIX_FMT_YUYV; camera.options.format = V4L2_PIX_FMT_MJPEG; camera.options.allow_dma = false; + // camera.options.nbufs = 1; if (camera_open(&camera) < 0) { goto error; diff --git a/http/http.c b/http/http.c index 7a1fabe..06226de 100644 --- a/http/http.c +++ b/http/http.c @@ -14,7 +14,7 @@ #define BUFSIZE 256 -static int http_listen(int listen_port, int maxcons) +static int http_listen(int port, int maxcons) { struct sockaddr_in server = {0}; int listenfd = -1; @@ -22,7 +22,7 @@ static int http_listen(int listen_port, int maxcons) // getaddrinfo for host server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; - server.sin_port = htons(listen_port); + server.sin_port = htons(port); listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd < 0) { @@ -124,7 +124,7 @@ error: int http_server(http_server_options_t *options, http_method_t *methods) { - int listen_fd = http_listen(options->listen_port, options->maxcons); + int listen_fd = http_listen(options->port, options->maxcons); if (listen_fd < 0) { return -1; } @@ -133,7 +133,7 @@ int http_server(http_server_options_t *options, http_method_t *methods) for (int worker = 0; worker < options->maxcons; worker++) { char name[20]; - sprintf(name, "HTTP%d/%d", options->listen_port, worker); + sprintf(name, "HTTP%d/%d", options->port, worker); http_worker_t *worker = calloc(1, sizeof(http_worker_t)); worker->name = strdup(name); diff --git a/http/http.h b/http/http.h index bd2d58f..ffc8d22 100644 --- a/http/http.h +++ b/http/http.h @@ -29,7 +29,7 @@ typedef struct http_worker_s { } http_worker_t; typedef struct http_server_options_s { - int listen_port; + int port; int maxcons; } http_server_options_t; diff --git a/hw/buffer_list.c b/hw/buffer_list.c index c8e52dd..d8cc4f4 100644 --- a/hw/buffer_list.c +++ b/hw/buffer_list.c @@ -89,11 +89,15 @@ retry: bytesperline = 0; } + E_LOG_DEBUG(buf_list, "Get current format ..."); + E_XIOCTL(buf_list, buf_list->device->fd, VIDIOC_G_FMT, fmt, "Can't set format"); + if (buf_list->do_mplanes) { fmt->fmt.pix_mp.colorspace = V4L2_COLORSPACE_JPEG; fmt->fmt.pix_mp.width = width; fmt->fmt.pix_mp.height = height; - fmt->fmt.pix_mp.pixelformat = format; + if (format) + fmt->fmt.pix_mp.pixelformat = format; fmt->fmt.pix_mp.field = V4L2_FIELD_ANY; fmt->fmt.pix_mp.num_planes = 1; fmt->fmt.pix_mp.plane_fmt[0].bytesperline = bytesperline; @@ -102,7 +106,8 @@ retry: fmt->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; fmt->fmt.pix.width = width; fmt->fmt.pix.height = height; - fmt->fmt.pix.pixelformat = format; + if (format) + fmt->fmt.pix.pixelformat = format; fmt->fmt.pix.field = V4L2_FIELD_ANY; fmt->fmt.pix.bytesperline = bytesperline; //fmt->fmt.pix.sizeimage = bytesperline * orig_height; @@ -138,7 +143,7 @@ retry: } } - if (buf_list->fmt_format != format) { + if (format && buf_list->fmt_format != format) { E_LOG_ERROR(buf_list, "Could not obtain the requested format=%s; driver gave us %s", fourcc_to_string(format).buf, fourcc_to_string(buf_list->fmt_format).buf); diff --git a/opts/opts.c b/opts/opts.c new file mode 100644 index 0000000..a338b6f --- /dev/null +++ b/opts/opts.c @@ -0,0 +1,74 @@ +#include "opts.h" +#include "hw/v4l2.h" + +#include +#include + +static void print_help(option_t *options) +{ + for (int i = 0; options[i].name; i++) { + printf("%20s ", options[i].name); + + if (options[i].ptr) { + printf(options[i].format, options[i].ptr); + } else { + printf(options[i].format, *options[i].value); + } + printf("\n"); + } +} + +static int parse_opt(option_t *options, const char *key, const char *value) +{ + option_t *option = NULL; + + for (int i = 0; options[i].name; i++) { + if (!strcmp(key, options[i].name)) { + option = &options[i]; + break; + } + } + + if (!option) { + return -EINVAL; + } + + int ret = 0; + if (option->ptr) { + ret = sscanf(value, option->format, option->ptr); + } else { + ret = sscanf(value, option->format, option->value); + } + return ret; +} + +int parse_opts(option_t *options, int argc, char *argv[]) +{ + int arg; + + for (arg = 1; arg < argc; arg += 2) { + const char *key = argv[arg]; + if (!strcmp(key, "-help")) { + print_help(options); + return -1; + } + + if (arg+1 == argc) { + E_LOG_ERROR(NULL, "The %s is missing argument.", key); + } + + if (key[0] != '-') { + E_LOG_ERROR(NULL, "The '%s' is not option (should start with -).", key); + } + + int ret = parse_opt(options, key+1, argv[arg+1]); + if (ret <= 0) { + E_LOG_ERROR(NULL, "Parsing '%s %s' returned '%d'.", key, argv[arg+1], ret); + } + } + + return 0; + +error: + return -1; +} diff --git a/opts/opts.h b/opts/opts.h new file mode 100644 index 0000000..084629c --- /dev/null +++ b/opts/opts.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +typedef struct options_s { + const char *name; + void *ptr; + union { + unsigned *value; + unsigned *value_uint; + bool *value_bool; + }; + const char *format; + const char *help; + unsigned size; +} option_t; + +#define lambda(return_type, function_body) \ +({ \ + return_type __fn__ function_body \ + __fn__; \ +}) + +#define OPTION_FORMAT_uint "%d" +#define OPTION_FORMAT_bool "%d" + +#define DEFINE_OPTION(_section, _name, _type) \ + { \ + .name = #_section "-" #_name, \ + .value_##_type = &_section##_options._name, \ + .format = OPTION_FORMAT_##_type, \ + .size = sizeof(_section##_options._name), \ + } + +#define DEFINE_OPTION_PTR(_section, _name, _format) \ + { \ + .name = #_section "-" #_name, \ + .ptr = _section##_options._name, \ + .format = _format, \ + .size = sizeof(_section##_options._name), \ + } + +int parse_opts(option_t *options, int argc, char *argv[]);