diff --git a/cmd/camera.c b/cmd/camera.c index 18ba4c9..3aa8ec3 100644 --- a/cmd/camera.c +++ b/cmd/camera.c @@ -9,13 +9,6 @@ void camera_init(camera_t *camera) { memset(camera, 0, sizeof(*camera)); camera->name = "CAMERA"; - strcpy(camera->options.path, "/dev/video0"); - camera->options.width = 1280; - camera->options.height = 720; - camera->options.nbufs = 4; - camera->options.format = V4L2_PIX_FMT_SRGGB10P; - camera->options.allow_dma = true; - camera->options.fps = 30; } void camera_close(camera_t *camera) @@ -32,13 +25,18 @@ void camera_close(camera_t *camera) int camera_open(camera_t *camera) { - camera->camera = device_open("CAMERA", camera->options.path); + camera->camera = device_open(camera->name, camera->options.path); if (!camera->camera) { return -1; } camera->camera->allow_dma = camera->options.allow_dma; + if (strstr(camera->camera->v4l2_cap.bus_info, "usb")) { + E_LOG_INFO(camera, "Disabling DMA since device uses USB (which is likely not working properly)."); + camera->camera->allow_dma = false; + } + if (device_open_buffer_list(camera->camera, true, camera->options.width, camera->options.height, camera->options.format, 0, camera->options.nbufs, true) < 0) { return -1; } diff --git a/cmd/camera.h b/cmd/camera.h index 23c91dd..1632d9b 100644 --- a/cmd/camera.h +++ b/cmd/camera.h @@ -13,6 +13,8 @@ typedef struct camera_options_s { unsigned width, height, format; unsigned nbufs, fps; bool allow_dma; + float high_res_factor; + float low_res_factor; } camera_options_t; typedef struct camera_s { @@ -33,7 +35,9 @@ typedef struct camera_s { device_t *codec_h264; // encode YUVU into H264 }; }; + link_t links[MAX_DEVICES]; + int nlinks; } camera_t; #define CAMERA(DEVICE) camera->devices[DEVICE] diff --git a/cmd/main.c b/cmd/main.c index 550efe0..4daae3a 100644 --- a/cmd/main.c +++ b/cmd/main.c @@ -28,7 +28,9 @@ camera_options_t camera_options = { .format = 0, .nbufs = 4, .fps = 30, - .allow_dma = true + .allow_dma = true, + .high_res_factor = 1.0, + .low_res_factor = 0.0, }; http_server_options_t http_options = { @@ -41,14 +43,25 @@ log_options_t log_options = { .verbose = false }; +option_value_t camera_formats[] = { + { "DEFAULT", 0 }, + { "YUYV", V4L2_PIX_FMT_YUYV }, + { "MJPEG", V4L2_PIX_FMT_MJPEG }, + { "H264", V4L2_PIX_FMT_H264 }, + { "RG10", V4L2_PIX_FMT_SRGGB10P }, + {} +}; + option_t all_options[] = { - DEFINE_OPTION_PTR(camera, path, "%s"), + DEFINE_OPTION_PTR(camera, path, string), DEFINE_OPTION(camera, width, uint), DEFINE_OPTION(camera, height, uint), - DEFINE_OPTION(camera, format, uint), + DEFINE_OPTION_VALUES(camera, format, camera_formats), DEFINE_OPTION(camera, nbufs, uint), DEFINE_OPTION(camera, fps, uint), DEFINE_OPTION(camera, allow_dma, bool), + DEFINE_OPTION(camera, high_res_factor, float), + DEFINE_OPTION(camera, low_res_factor, float), DEFINE_OPTION(http, port, uint), DEFINE_OPTION(http, maxcons, uint), DEFINE_OPTION(log, debug, bool), diff --git a/hw/buffer_queue.c b/hw/buffer_queue.c index d991b4e..f46e0cd 100644 --- a/hw/buffer_queue.c +++ b/hw/buffer_queue.c @@ -106,6 +106,9 @@ int buffer_list_enqueue(buffer_list_t *buf_list, buffer_t *dma_buf) return 0; } + buf->v4l2_buffer.flags &= ~V4L2_BUF_FLAG_KEYFRAME; + buf->v4l2_buffer.flags |= dma_buf->v4l2_buffer.flags & V4L2_BUF_FLAG_KEYFRAME; + if (buf_list->do_mmap) { if (dma_buf->used > buf->length) { E_LOG_INFO(buf_list, "The dma_buf (%s) is too long: %zu vs space=%zu", diff --git a/opts/opts.c b/opts/opts.c index a338b6f..9785700 100644 --- a/opts/opts.c +++ b/opts/opts.c @@ -7,13 +7,24 @@ static void print_help(option_t *options) { for (int i = 0; options[i].name; i++) { - printf("%20s ", options[i].name); + option_t *option = &options[i]; + printf("%40s\t", option->name); - if (options[i].ptr) { - printf(options[i].format, options[i].ptr); + if (option->value_string) { + printf(option->format, option->value_string); + } else if (option->value_mapping) { + for (int j = 0; option->value_mapping[j].name; j++) { + if (option->value_mapping[j].value == *option->value) { + printf("%s - ", option->value_mapping[j].name); + break; + } + } + + printf(option->format, *option->value); } else { - printf(options[i].format, *options[i].value); + printf(option->format, *option->value); } + printf("\n"); } } @@ -34,8 +45,17 @@ static int parse_opt(option_t *options, const char *key, const char *value) } int ret = 0; - if (option->ptr) { - ret = sscanf(value, option->format, option->ptr); + if (option->value_string) { + ret = sscanf(value, option->format, option->value_string); + } else if (option->value_mapping) { + for (int j = 0; option->value_mapping[j].name; j++) { + if (!strcmp(option->value_mapping[j].name, value)) { + *option->value_uint = option->value_mapping[j].value; + return 1; + } + } + + ret = sscanf(value, option->format, option->value); } else { ret = sscanf(value, option->format, option->value); } diff --git a/opts/opts.h b/opts/opts.h index 084629c..e3db6db 100644 --- a/opts/opts.h +++ b/opts/opts.h @@ -2,16 +2,24 @@ #include +typedef struct option_value_s { + const char *name; + unsigned value; +} option_value_t; + typedef struct options_s { const char *name; - void *ptr; + char *value_string; union { unsigned *value; unsigned *value_uint; + unsigned *value_hex; bool *value_bool; + float *value_float; }; const char *format; const char *help; + option_value_t *value_mapping; unsigned size; } option_t; @@ -21,8 +29,11 @@ typedef struct options_s { __fn__; \ }) -#define OPTION_FORMAT_uint "%d" -#define OPTION_FORMAT_bool "%d" +#define OPTION_FORMAT_uint "%d" +#define OPTION_FORMAT_hex "%08x" +#define OPTION_FORMAT_bool "%d" +#define OPTION_FORMAT_float "%.1f" +#define OPTION_FORMAT_string "%s" #define DEFINE_OPTION(_section, _name, _type) \ { \ @@ -32,11 +43,20 @@ typedef struct options_s { .size = sizeof(_section##_options._name), \ } -#define DEFINE_OPTION_PTR(_section, _name, _format) \ +#define DEFINE_OPTION_VALUES(_section, _name, _value_mapping) \ { \ .name = #_section "-" #_name, \ - .ptr = _section##_options._name, \ - .format = _format, \ + .value_hex = &_section##_options._name, \ + .format = OPTION_FORMAT_hex, \ + .value_mapping = _value_mapping, \ + .size = sizeof(_section##_options._name), \ + } + +#define DEFINE_OPTION_PTR(_section, _name, _type) \ + { \ + .name = #_section "-" #_name, \ + .value_##_type = _section##_options._name, \ + .format = OPTION_FORMAT_##_type, \ .size = sizeof(_section##_options._name), \ }