瀏覽代碼

Merge branch 'master' into add_more_formats

Kristian Vos 10 月之前
父節點
當前提交
fef81ad5d9
共有 10 個文件被更改,包括 151 次插入63 次删除
  1. 15 2
      .gitlab-ci.yml
  2. 4 0
      CMakeLists.txt
  3. 31 30
      config/pine64,pinephone-pro.conf
  4. 1 1
      config/pine64,pinephone.conf
  5. 0 18
      config/xiaomi,scorpio.conf
  6. 22 0
      configtest.sh
  7. 3 0
      include/libmegapixels.h
  8. 5 0
      meson.build
  9. 35 12
      src/parse.c
  10. 35 0
      util/configlint.c

+ 15 - 2
.gitlab-ci.yml

@@ -1,5 +1,5 @@
 build:
-  stage: test
+  stage: build
   image: alpine:edge
   before_script:
     - apk add --no-cache build-base meson samurai linux-headers libconfig-dev scdoc
@@ -7,9 +7,12 @@ build:
     - meson build --buildtype release --werror
     - ninja -C build
     - cd build && meson test --no-rebuild
+  artifacts:
+    paths:
+      - build
 
 docs:
-  stage: test
+  stage: build
   image: alpine:edge
   before_script:
     - apk add --no-cache python3 py3-sphinx make
@@ -17,6 +20,16 @@ docs:
     - cd docs
     - make html
 
+lint:
+  stage: test
+  dependencies:
+    - build
+  image: alpine:edge
+  before_script:
+    - apk add --no-cache libconfig bash
+  script:
+    - bash ./configtest.sh
+
 pages:
   stage: deploy
   image: alpine:edge

+ 4 - 0
CMakeLists.txt

@@ -28,6 +28,10 @@ add_executable(sensorprofile util/sensorprofile.c)
 target_include_directories(sensorprofile PUBLIC include)
 target_link_libraries(sensorprofile PUBLIC megapixels)
 
+add_executable(configlint util/configlint.c)
+target_include_directories(configlint PUBLIC include)
+target_link_libraries(configlint PUBLIC megapixels)
+
 add_compile_definitions(SYSCONFDIR="/etc")
 add_compile_definitions(DATADIR="/usr/share")
 

+ 31 - 30
config/pine64,pinephone-pro.conf

@@ -5,6 +5,7 @@ Model: "PinePhone Pro";
 Rear: {
     SensorDriver: "imx258";
     BridgeDriver: "rkisp1";
+    FlashPath: "/sys/class/leds/white:flash";
 
     Modes: (
         {
@@ -30,7 +31,7 @@ Rear: {
                 {Type: "Mode", Entity: "rkisp1_resizer_mainpath", Pad: 1}
             );
         },
-        # { # Doesn't work in megapixels yet
+        # { # Doesn't work well in Megapixels yet
         #     Width: 4208;
         #     Height: 3120;
         #     Rate: 30;
@@ -67,14 +68,14 @@ Rear: {
                 {Type: "Link", From: "rkisp1_csi", FromPad: 1, To: "rkisp1_isp", ToPad: 0},
                 {Type: "Link", From: "rkisp1_isp", FromPad: 2, To: "rkisp1_resizer_mainpath", ToPad: 0},
                 {Type: "Mode", Entity: "imx258", Format: "RGGB10P"},
-                {Type: "Mode", Entity: "rkisp1_csi", Pad: 0},
-                {Type: "Mode", Entity: "rkisp1_isp", Pad: 0},
+                {Type: "Mode", Entity: "rkisp1_csi"},
+                {Type: "Mode", Entity: "rkisp1_isp"},
                 {Type: "Mode", Entity: "rkisp1_isp", Pad: 2, Format: "RGGB8"},
-                {Type: "Mode", Entity: "rkisp1_resizer_mainpath", Pad: 0},
+                {Type: "Mode", Entity: "rkisp1_resizer_mainpath"},
                 {Type: "Mode", Entity: "rkisp1_resizer_mainpath", Pad: 1},
-                {Type: "Crop", Entity: "rkisp1_isp", Pad: 0},
+                {Type: "Crop", Entity: "rkisp1_isp"},
                 {Type: "Crop", Entity: "rkisp1_isp", Pad: 2},
-                {Type: "Crop", Entity: "rkisp1_resizer_mainpath", Pad: 0},
+                {Type: "Crop", Entity: "rkisp1_resizer_mainpath"}
             );
         },
     );
@@ -108,12 +109,12 @@ Front: {
                 {Type: "Mode", Entity: "rkisp1_resizer_mainpath", Pad: 1}
             );
         },
-        # { # Doesn't work in megapixels yet
+        # { # Doesn't work well in Megapixels yet
         #     Width: 3264;
         #     Height: 2448;
         #     Rate: 30;
         #     Format: "BGGR10";
-        #     Rotate: 270;
+        #     Rotate: 90;
         #     FocalLength: 3.33;
         #     FNumber: 3.0;
 
@@ -131,28 +132,28 @@ Front: {
         #         {Type: "Mode", Entity: "rkisp1_resizer_mainpath", Pad: 1}
         #     );
         # },
-        # { # Doesn't work in megapixels yet
-        #     Width: 1632;
-        #     Height: 1224;
-        #     Rate: 30;
-        #     Format: "YUYV";
-        #     Rotate: 270;
-        #     FocalLength: 3.33;
-        #     FNumber: 3.0;
+        {
+            Width: 1048;
+            Height: 780;
+            Rate: 30;
+            Format: "BGGR8";
+            Rotate: 90;
+            FocalLength: 3.33;
+            FNumber: 3.0;
 
-        #     Pipeline: (
-        #         {Type: "Link", From: "ov8858", FromPad: 0, To: "rkisp1_csi", ToPad: 0},
-        #         {Type: "Link", From: "rkisp1_csi", FromPad: 1, To: "rkisp1_isp", ToPad: 0},
-        #         {Type: "Link", From: "rkisp1_isp", FromPad: 2, To: "rkisp1_resizer_selfpath", ToPad: 0},
-        #         {Type: "Mode", Entity: "ov8858", Format: "BGGR10"},
-        #         {Type: "Mode", Entity: "rkisp1_csi"},
-        #         {Type: "Mode", Entity: "rkisp1_isp"},
-        #         {Type: "Mode", Entity: "rkisp1_isp", Pad: 2, Format: "YUYV"},
-        #         {Type: "Crop", Entity: "rkisp1_isp"}, # Cropped by default
-        #         {Type: "Crop", Entity: "rkisp1_isp", Pad: 2}, # Cropped by default
-        #         {Type: "Mode", Entity: "rkisp1_resizer_selfpath"},
-        #         {Type: "Mode", Entity: "rkisp1_resizer_selfpath", Pad: 1}
-        #     );
-        # }
+            Pipeline: (
+                {Type: "Link", From: "ov8858", FromPad: 0, To: "rkisp1_csi", ToPad: 0},
+                {Type: "Link", From: "rkisp1_csi", FromPad: 1, To: "rkisp1_isp", ToPad: 0},
+                {Type: "Link", From: "rkisp1_isp", FromPad: 2, To: "rkisp1_resizer_mainpath", ToPad: 0},
+                {Type: "Mode", Entity: "ov8858", Format: "BGGR10", Width: 1632, Height: 1224},
+                {Type: "Mode", Entity: "rkisp1_csi"},
+                {Type: "Mode", Entity: "rkisp1_isp"},
+                {Type: "Mode", Entity: "rkisp1_isp", Pad: 2, Format: "BGGR8", Width: 1048, Height: 780},
+                {Type: "Crop", Entity: "rkisp1_isp"}, # Cropped by default
+                {Type: "Crop", Entity: "rkisp1_isp", Pad: 2}, # Cropped by default
+                {Type: "Mode", Entity: "rkisp1_resizer_mainpath"},
+                {Type: "Mode", Entity: "rkisp1_resizer_mainpath", Pad: 1}
+            );
+        }
     );
 };

+ 1 - 1
config/pine64,pinephone.conf

@@ -37,7 +37,7 @@ Rear: {
                 {Type: "Link", From: "ov5640", FromPad: 0, To: "sun6i-csi", ToPad: 0},
                 {Type: "Mode", Entity: "ov5640"}
             );
-        }
+        },
         {
             Width: 1280;
             Height: 720;

+ 0 - 18
config/xiaomi,scorpio.conf

@@ -14,24 +14,6 @@ Rear: {
             Format: "RGGB10p";
             Rotate: 90;
 
-            Pipeline: (
-                {Type: "Link", From: "msm_csiphy0", FromPad: 1, To: "msm_csid0", ToPad: 0},
-                {Type: "Link", From: "msm_csid0", FromPad: 1, To: "msm_ispif0", ToPad: 0},
-                {Type: "Link", From: "msm_ispif0", FromPad: 1, To: "msm_vfe0_rdi0", ToPad: 0},
-                {Type: "Mode", Entity: "imx318"},
-                {Type: "Mode", Entity: "msm_csiphy0"},
-                {Type: "Mode", Entity: "msm_csid0"},
-                {Type: "Mode", Entity: "msm_ispif0"},
-                {Type: "Mode", Entity: "msm_vfe0_rdi0"},
-            );
-        },
-        {
-            Width: 1280;
-            Height: 720;
-            Rate: 30;
-            Format: "UYUV";
-            Rotate: 90;
-
             Pipeline: (
                 {Type: "Link", From: "msm_csiphy0", FromPad: 1, To: "msm_csid0", ToPad: 0},
                 {Type: "Link", From: "msm_csid0", FromPad: 1, To: "msm_ispif0", ToPad: 0},

+ 22 - 0
configtest.sh

@@ -0,0 +1,22 @@
+#!/bin/bash
+
+RED='\033[0;31m'
+BOLDRED='\033[1;31m'
+GREEN='\033[0;32m'
+CLEAR='\033[0m'
+
+ret=0
+for cfg in $(find config/ -type f -iname *.conf)
+do
+  printf "%s: " $cfg
+  errors=$(./build/megapixels-configlint "$cfg" 2>&1)
+  if [ -z "$errors" ] ; then
+    echo -e "${GREEN}PASS${CLEAR}"
+  else
+    ret=1
+    echo -e "${BOLDRED}FAIL${CLEAR}"
+    echo -e "${RED}$errors${CLEAR}"
+    echo ""
+  fi
+done
+exit $ret

+ 3 - 0
include/libmegapixels.h

@@ -129,6 +129,9 @@ libmegapixels_loglevel(int loglevel);
 EXPORT int
 libmegapixels_load_file(libmegapixels_devconfig *config, const char *file);
 
+EXPORT int
+libmegapixels_load_file_lint(libmegapixels_devconfig *config, const char *file, int linting);
+
 EXPORT int
 libmegapixels_load_uvc(libmegapixels_devconfig *config);
 

+ 5 - 0
meson.build

@@ -64,6 +64,11 @@ executable('megapixels-getframe', 'util/getframe.c',
     include_directories: inc,
     install: true,
     )
+executable('megapixels-configlint', 'util/configlint.c',
+    link_with: libmegapixels,
+    include_directories: inc,
+    install: true,
+    )
 
 cc = meson.get_compiler('c')
 m_dep = cc.find_library('m', required : false)

+ 35 - 12
src/parse.c

@@ -177,7 +177,7 @@ find_media_node(libmegapixels_camera *camera, const char *media_name, const char
 }
 
 int
-load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name)
+load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name, int lint)
 {
 	const char *sensor_driver, *bridge_driver;
 	config_setting_t *root = config_lookup(cfg, name);
@@ -196,11 +196,14 @@ load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name)
 	camera->media_fd = 0;
 	camera->video_fd = 0;
 
-	int res = find_media_node(camera, bridge_driver, sensor_driver);
-	if (res < 0) {
-		log_debug("  Could not find media node with this sensor\n");
-		free(camera);
-		return -1;
+	// Don't access hardware in linting mode
+	if (lint == 0) {
+		int res = find_media_node(camera, bridge_driver, sensor_driver);
+		if (res < 0) {
+			log_debug("  Could not find media node with this sensor\n");
+			free(camera);
+			return -1;
+		}
 	}
 
 	camera->name = strdup(name);
@@ -216,6 +219,11 @@ load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name)
 	config_setting_t *modes = config_setting_lookup(root, "Modes");
 	config_setting_t *mode;
 
+	if (modes == NULL) {
+		log_error("Sensor '%s' does not define any modes\n", camera->name);
+		return -1;
+	}
+
 	int num_modes = config_setting_length(modes);
 	camera->modes = malloc(num_modes * sizeof(libmegapixels_mode *));
 	camera->num_modes = num_modes;
@@ -381,11 +389,22 @@ load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name)
 		n++;
 	}
 
+	if (n == 0) {
+		log_debug("No modes defined for sensor '%s'\n", camera->name);
+		return -1;
+	}
+
 	return 0;
 }
 
 int
 libmegapixels_load_file(libmegapixels_devconfig *config, const char *file)
+{
+	return libmegapixels_load_file_lint(config, file, 0);
+}
+
+int
+libmegapixels_load_file_lint(libmegapixels_devconfig *config, const char *file, int linting)
 {
 	if (config->loaded_config) {
 		log_error("Config already loaded\n");
@@ -403,9 +422,13 @@ libmegapixels_load_file(libmegapixels_devconfig *config, const char *file)
 
 	config_init(&cfg);
 	if (!config_read_file(&cfg, file)) {
-		fprintf(stderr, "Could not read %s\n", file);
-		fprintf(stderr, "%s:%d - %s\n",
-			config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
+		if (config_error_type(&cfg) == CONFIG_ERR_FILE_IO) {
+			fprintf(stderr, "Could not read %s: %s\n", file, config_error_text(&cfg));
+		} else {
+			fprintf(stderr, "Could not read %s:\n", file);
+			fprintf(stderr, "\t%s:%d - %s\n",
+				config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
+		}
 		config_destroy(&cfg);
 		return 0;
 	}
@@ -413,11 +436,11 @@ libmegapixels_load_file(libmegapixels_devconfig *config, const char *file)
 	int version = 0;
 	if (config_lookup_int(&cfg, "Version", &version)) {
 		if (version != 1) {
-			fprintf(stderr, "Invalid version %d\n", version);
+			fprintf(stderr, "Could not load '%s': Invalid version %d\n", file, version);
 			return 0;
 		}
 	} else {
-		fprintf(stderr, "Missing version\n");
+		fprintf(stderr, "Could not load '%s': Missing version\n", file);
 		return 0;
 	}
 
@@ -446,7 +469,7 @@ libmegapixels_load_file(libmegapixels_devconfig *config, const char *file)
 		if (strcmp(member->name, "Model") == 0) {
 			continue;
 		}
-		load_camera(config, &cfg, member->name);
+		load_camera(config, &cfg, member->name, linting);
 	}
 
 	return 1;

+ 35 - 0
util/configlint.c

@@ -0,0 +1,35 @@
+#include <libmegapixels.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+int
+main(int argc, char *argv[])
+{
+	if (argc != 2) {
+		fprintf(stderr, "Usage: %s <configfile>\n", argv[0]);
+		return 1;
+	}
+
+	libmegapixels_devconfig *config = {0};
+	libmegapixels_init(&config);
+	if (!libmegapixels_load_file_lint(config, argv[1], 1)) {
+		return 1;
+	}
+
+	if (config->count == 0) {
+		fprintf(stderr, "Config file does not define any cameras\n");
+		return 1;
+	}
+
+	bool faulty = false;
+	for (int i = 0; i < config->count; i++) {
+		if (config->cameras[i]->num_modes == 0) {
+			fprintf(stderr, "No modes are defined for sensor '%s'\n", config->cameras[i]->name);
+			faulty = true;
+		}
+	}
+	if (faulty) {
+		return 1;
+	}
+	return 0;
+}