123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- #include "camera_config.h"
- #include "ini.h"
- #include "config.h"
- #include "matrix.h"
- #include <wordexp.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <glib.h>
- #include <assert.h>
- static struct mp_camera_config cameras[MP_MAX_CAMERAS];
- static size_t num_cameras = 0;
- static char *exif_make;
- static char *exif_model;
- static bool
- find_config(char *conffile)
- {
- char buf[512];
- char *xdg_config_home;
- wordexp_t exp_result;
- FILE *fp;
- // Resolve XDG stuff
- if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) {
- xdg_config_home = "~/.config";
- }
- wordexp(xdg_config_home, &exp_result, 0);
- xdg_config_home = strdup(exp_result.we_wordv[0]);
- wordfree(&exp_result);
- if (access("/proc/device-tree/compatible", F_OK) != -1) {
- // Reads to compatible string of the current device tree, looks like:
- // pine64,pinephone-1.2\0allwinner,sun50i-a64\0
- fp = fopen("/proc/device-tree/compatible", "r");
- fgets(buf, 512, fp);
- fclose(fp);
- // Check config/%dt.ini in the current working directory
- sprintf(conffile, "config/%s.ini", buf);
- if (access(conffile, F_OK) != -1) {
- printf("Found config file at %s\n", conffile);
- return true;
- }
- // Check for a config file in XDG_CONFIG_HOME
- sprintf(conffile, "%s/megapixels/config/%s.ini", xdg_config_home,
- buf);
- if (access(conffile, F_OK) != -1) {
- printf("Found config file at %s\n", conffile);
- return true;
- }
- // Check user overridden /etc/megapixels/config/$dt.ini
- sprintf(conffile, "%s/megapixels/config/%s.ini", SYSCONFDIR, buf);
- if (access(conffile, F_OK) != -1) {
- printf("Found config file at %s\n", conffile);
- return true;
- }
- // Check packaged /usr/share/megapixels/config/$dt.ini
- sprintf(conffile, "%s/megapixels/config/%s.ini", DATADIR, buf);
- if (access(conffile, F_OK) != -1) {
- printf("Found config file at %s\n", conffile);
- return true;
- }
- printf("%s not found\n", conffile);
- } else {
- printf("Could not read device name from device tree\n");
- }
- // If all else fails, fall back to /etc/megapixels.ini
- sprintf(conffile, "/etc/megapixels.ini");
- if (access(conffile, F_OK) != -1) {
- printf("Found config file at %s\n", conffile);
- return true;
- }
- return false;
- }
- static int
- strtoint(const char *nptr, char **endptr, int base)
- {
- long x = strtol(nptr, endptr, base);
- assert(x <= INT_MAX);
- return (int)x;
- }
- static bool
- config_handle_camera_mode(const char *prefix, MPCameraMode *mode, const char *name,
- const char *value)
- {
- int prefix_length = strlen(prefix);
- if (strncmp(prefix, name, prefix_length) != 0)
- return false;
- name += prefix_length;
- if (strcmp(name, "width") == 0) {
- mode->width = strtoint(value, NULL, 10);
- } else if (strcmp(name, "height") == 0) {
- mode->height = strtoint(value, NULL, 10);
- } else if (strcmp(name, "rate") == 0) {
- mode->frame_interval.numerator = 1;
- mode->frame_interval.denominator = strtoint(value, NULL, 10);
- } else if (strcmp(name, "fmt") == 0) {
- mode->pixel_format = mp_pixel_format_from_str(value);
- if (mode->pixel_format == MP_PIXEL_FMT_UNSUPPORTED) {
- g_printerr("Unsupported pixelformat %s\n", value);
- exit(1);
- }
- } else {
- return false;
- }
- return true;
- }
- static int
- config_ini_handler(void *user, const char *section, const char *name,
- const char *value)
- {
- if (strcmp(section, "device") == 0) {
- if (strcmp(name, "make") == 0) {
- exif_make = strdup(value);
- } else if (strcmp(name, "model") == 0) {
- exif_model = strdup(value);
- } else {
- g_printerr("Unknown key '%s' in [device]\n", name);
- exit(1);
- }
- } else {
- if (num_cameras == MP_MAX_CAMERAS) {
- g_printerr("More cameras defined than NUM_CAMERAS\n");
- exit(1);
- }
- size_t index = 0;
- for (; index < num_cameras; ++index) {
- if (strcmp(cameras[index].cfg_name, section) == 0) {
- break;
- }
- }
- if (index == num_cameras) {
- printf("Adding camera %s from config\n", section);
- ++num_cameras;
- cameras[index].index = index;
- strcpy(cameras[index].cfg_name, section);
- }
- struct mp_camera_config *cc = &cameras[index];
- if (config_handle_camera_mode("capture-", &cc->capture_mode, name,
- value)) {
- } else if (config_handle_camera_mode("preview-", &cc->preview_mode,
- name, value)) {
- } else if (strcmp(name, "rotate") == 0) {
- cc->rotate = strtoint(value, NULL, 10);
- } else if (strcmp(name, "mirrored") == 0) {
- cc->mirrored = strcmp(value, "true") == 0;
- } else if (strcmp(name, "driver") == 0) {
- strcpy(cc->dev_name, value);
- } else if (strcmp(name, "media-driver") == 0) {
- strcpy(cc->media_dev_name, value);
- } else if (strcmp(name, "media-links") == 0) {
- char **linkdefs = g_strsplit(value, ",", 0);
- for (int i = 0; i < MP_MAX_LINKS && linkdefs[i] != NULL;
- ++i) {
- char **linkdef = g_strsplit(linkdefs[i], "->", 2);
- char **porta = g_strsplit(linkdef[0], ":", 2);
- char **portb = g_strsplit(linkdef[1], ":", 2);
- strcpy(cc->media_links[i].source_name, porta[0]);
- strcpy(cc->media_links[i].target_name, portb[0]);
- cc->media_links[i].source_port =
- strtoint(porta[1], NULL, 10);
- cc->media_links[i].target_port =
- strtoint(portb[1], NULL, 10);
- g_strfreev(portb);
- g_strfreev(porta);
- g_strfreev(linkdef);
- ++cc->num_media_links;
- }
- g_strfreev(linkdefs);
- } else if (strcmp(name, "colormatrix") == 0) {
- sscanf(value, "%f,%f,%f,%f,%f,%f,%f,%f,%f",
- cc->colormatrix + 0, cc->colormatrix + 1,
- cc->colormatrix + 2, cc->colormatrix + 3,
- cc->colormatrix + 4, cc->colormatrix + 5,
- cc->colormatrix + 6, cc->colormatrix + 7,
- cc->colormatrix + 8);
- } else if (strcmp(name, "forwardmatrix") == 0) {
- sscanf(value, "%f,%f,%f,%f,%f,%f,%f,%f,%f",
- cc->forwardmatrix + 0, cc->forwardmatrix + 1,
- cc->forwardmatrix + 2, cc->forwardmatrix + 3,
- cc->forwardmatrix + 4, cc->forwardmatrix + 5,
- cc->forwardmatrix + 6, cc->forwardmatrix + 7,
- cc->forwardmatrix + 8);
- } else if (strcmp(name, "whitelevel") == 0) {
- cc->whitelevel = strtoint(value, NULL, 10);
- } else if (strcmp(name, "blacklevel") == 0) {
- cc->blacklevel = strtoint(value, NULL, 10);
- } else if (strcmp(name, "focallength") == 0) {
- cc->focallength = strtof(value, NULL);
- } else if (strcmp(name, "cropfactor") == 0) {
- cc->cropfactor = strtof(value, NULL);
- } else if (strcmp(name, "fnumber") == 0) {
- cc->fnumber = strtod(value, NULL);
- } else if (strcmp(name, "iso-min") == 0) {
- cc->iso_min = strtod(value, NULL);
- } else if (strcmp(name, "iso-max") == 0) {
- cc->iso_max = strtod(value, NULL);
- } else {
- g_printerr("Unknown key '%s' in [%s]\n", name, section);
- exit(1);
- }
- }
- return 1;
- }
- void
- calculate_matrices()
- {
- for (size_t i = 0; i < MP_MAX_CAMERAS; ++i) {
- if (cameras[i].colormatrix != NULL &&
- cameras[i].forwardmatrix != NULL) {
- multiply_matrices(cameras[i].colormatrix,
- cameras[i].forwardmatrix,
- cameras[i].previewmatrix);
- }
- }
- }
- bool
- mp_load_config()
- {
- char file[512];
- if (!find_config(file)) {
- g_printerr("Could not find any config file\n");
- return false;
- }
- int result = ini_parse(file, config_ini_handler, NULL);
- if (result == -1) {
- g_printerr("Config file not found\n");
- return false;
- }
- if (result == -2) {
- g_printerr("Could not allocate memory to parse config file\n");
- return false;
- }
- if (result != 0) {
- g_printerr("Could not parse config file\n");
- return false;
- }
- calculate_matrices();
- return true;
- }
- const char *
- mp_get_device_make()
- {
- return exif_make;
- }
- const char *
- mp_get_device_model()
- {
- return exif_model;
- }
- const struct mp_camera_config *
- mp_get_camera_config(size_t index)
- {
- if (index >= num_cameras)
- return NULL;
- return &cameras[index];
- }
|