diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 54b7183..f9c15d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: - name: install libs run: sudo apt install -y libglfw3-dev libgl-dev - name: gcc - run: mkdir -p build && gcc -v -Wall -Wextra -Werror src/*.c src/*.h -lglfw -lGL -lm -Iinclude hashmap.c/hashmap.c -DGLFW_INCLUDE_NONE -DGLFW_EXPOSE_NATIVE_EGL -DGLFW_NATIVE_INCLUDE_NONE + run: mkdir -p build && gcc -v -Wall -Wextra -Werror src/*.c src/*.h -lglfw -lGL -lm -Iinclude hashmap.c/hashmap.c log.c/src/log.c -DGLFW_INCLUDE_NONE -DGLFW_EXPOSE_NATIVE_EGL -DGLFW_NATIVE_INCLUDE_NONE build-release: needs: lint diff --git a/.gitmodules b/.gitmodules index 9c889b9..525427e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "hashmap.c"] path = hashmap.c url = https://github.com/tidwall/hashmap.c +[submodule "log.c"] + path = log.c + url = https://github.com/rxi/log.c diff --git a/Makefile.am b/Makefile.am index 17c151f..b1a12cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign subdir-objects -Wall bin_PROGRAMS = forge -forge_SOURCES = src/main.c src/args.c src/forge.c src/file.c src/window.c src/shaders.c src/timer.c src/string.c src/config_file.c src/rand.c src/video.c $(top_srcdir)/include/glad/gl.h $(top_srcdir)/include/glad/egl.h $(top_srcdir)/hashmap.c/hashmap.c -forge_CFLAGS = -Ofast -march=native -flto -funroll-loops -fprefetch-loop-arrays -fno-exceptions -fopenmp -I$(top_srcdir)/include -DGLFW_INCLUDE_NONE -DGLFW_EXPOSE_NATIVE_EGL -DGLFW_NATIVE_INCLUDE_NONE +forge_SOURCES = src/main.c src/args.c src/forge.c src/file.c src/window.c src/shaders.c src/timer.c src/string.c src/config_file.c src/rand.c src/video.c $(top_srcdir)/include/glad/gl.h $(top_srcdir)/include/glad/egl.h $(top_srcdir)/hashmap.c/hashmap.c $(top_srcdir)/log.c/src/log.c +forge_CFLAGS = -Ofast -march=native -flto -funroll-loops -fprefetch-loop-arrays -fno-exceptions -fopenmp -I$(top_srcdir)/include -DGLFW_INCLUDE_NONE -DGLFW_EXPOSE_NATIVE_EGL -DGLFW_NATIVE_INCLUDE_NONE -DLOG_USE_COLOR forge_LDADD = -lm -lGL -lglfw -include_HEADERS = src/main.h src/args.h src/config.h src/types.h src/forge.h src/file.h src/constants.h src/window.h src/shaders.h src/logs.h src/timer.h src/string.h src/config_file.h src/rand.h src/video.h $(top_srcdir)/include/glad/gl.h $(top_srcdir)/include/glad/egl.h $(top_srcdir)/include/linmath.h $(top_srcdir)/include/hashmap.h \ No newline at end of file +include_HEADERS = src/main.h src/args.h src/config.h src/types.h src/forge.h src/file.h src/constants.h src/window.h src/shaders.h src/timer.h src/string.h src/config_file.h src/rand.h src/video.h $(top_srcdir)/include/glad/gl.h $(top_srcdir)/include/glad/egl.h $(top_srcdir)/include/linmath.h $(top_srcdir)/include/hashmap.h $(top_srcdir)/include/log.h \ No newline at end of file diff --git a/Makefile.dev b/Makefile.dev index 99f8b09..67aa4ef 100644 --- a/Makefile.dev +++ b/Makefile.dev @@ -13,11 +13,13 @@ build: src/*.h src/*.c \ -Iinclude \ hashmap.c/hashmap.c \ + log.c/src/log.c \ -lm -lGL -lglfw -ldrm \ -Wall -Wextra \ -DGLFW_INCLUDE_NONE \ -DGLFW_EXPOSE_NATIVE_EGL \ -DGLFW_NATIVE_INCLUDE_NONE \ + -DLOG_USE_COLOR \ -o build/$(TARGET) \ -g diff --git a/README.md b/README.md index 321777c..2b37019 100644 --- a/README.md +++ b/README.md @@ -134,10 +134,11 @@ make -f Makefile.dev release-arch - [ ] Clean code and fix things - [ ] Video input - [x] Fixed camera video - - [ ] Pass video info to shaders - - [ ] Sub process video reading - - [ ] Shader based format mapping - - [ ] Video mapping config file + - [x] Pass video info to shaders + - [x] Sub process video reading + - [x] Shader based format mapping + - [x] Video mapping config file + - [ ] Get first video size matching internal size - [ ] Clean code and fix things - [x] Monitor screen - [x] 2nd window diff --git a/configure.ac b/configure.ac index 640f121..2b0d6cc 100644 --- a/configure.ac +++ b/configure.ac @@ -1,9 +1,11 @@ AC_INIT([forge], [0.0.0], [klemek.dev@proton.me]) AM_INIT_AUTOMAKE AC_PROG_CC +AC_CHECK_HEADERS([errno.h]) AC_CHECK_HEADERS([fcntl.h]) AC_CHECK_HEADERS([GLFW/glfw3.h]) AC_CHECK_HEADERS([GLFW/glfw3native.h]) +AC_CHECK_HEADERS([limits.h]) AC_CHECK_HEADERS([linux/videodev2.h]) AC_CHECK_HEADERS([math.h]) AC_CHECK_HEADERS([stdbool.h]) @@ -12,12 +14,12 @@ AC_CHECK_HEADERS([stdint.h]) AC_CHECK_HEADERS([stdio.h]) AC_CHECK_HEADERS([stdlib.h]) AC_CHECK_HEADERS([string.h]) -AC_CHECK_HEADERS([errno.h]) AC_CHECK_HEADERS([sys/ioctl.h]) AC_CHECK_HEADERS([sys/mman.h]) AC_CHECK_HEADERS([sys/stat.h]) AC_CHECK_HEADERS([sys/time.h]) AC_CHECK_HEADERS([sys/types.h]) +AC_CHECK_HEADERS([sys/wait.h]) AC_CHECK_HEADERS([time.h]) AC_CHECK_HEADERS([unistd.h]) AC_CONFIG_FILES([Makefile]) diff --git a/include/log.h b/include/log.h new file mode 120000 index 0000000..0ed3cb9 --- /dev/null +++ b/include/log.h @@ -0,0 +1 @@ +../log.c/src/log.h \ No newline at end of file diff --git a/log.c b/log.c new file mode 160000 index 0000000..f9ea349 --- /dev/null +++ b/log.c @@ -0,0 +1 @@ +Subproject commit f9ea34994bd58ed342d2245cd4110bb5c6790153 diff --git a/src/args.c b/src/args.c index 3203e42..b1c8fca 100644 --- a/src/args.c +++ b/src/args.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -6,7 +7,6 @@ #include "args.h" #include "config.h" -#include "logs.h" #include "string.h" #include "types.h" diff --git a/src/config_file.c b/src/config_file.c index ddfb2f4..eb1ba9b 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -1,10 +1,10 @@ #include +#include #include #include #include "config_file.h" #include "file.h" -#include "logs.h" #include "string.h" #include "types.h" diff --git a/src/file.c b/src/file.c index 0f74c64..c2200ba 100644 --- a/src/file.c +++ b/src/file.c @@ -1,13 +1,11 @@ -#include +#include #include #include #include #include -#include #include #include "file.h" -#include "logs.h" #include "string.h" #include "types.h" diff --git a/src/forge.c b/src/forge.c index ad83cbb..88b8802 100644 --- a/src/forge.c +++ b/src/forge.c @@ -1,13 +1,13 @@ -#include +#include #include #include #include +#include #include "config.h" #include "config_file.h" #include "file.h" #include "forge.h" -#include "logs.h" #include "rand.h" #include "shaders.h" #include "timer.h" @@ -24,6 +24,7 @@ static File *fragment_shaders; static File common_shader_code; static Timer timer; static ConfigFile shader_config; +static bool stop; static unsigned int compute_fps() { static double fps; @@ -154,14 +155,12 @@ static void init_devices(char *video_in[MAX_VIDEO], unsigned int video_count) { } } -static void update_devices(unsigned int video_count) { +static void start_devices(unsigned int video_count) { unsigned int i; for (i = 0; i < video_count; i++) { if (!devices[i].error) { - if (!video_read(&devices[i])) { - video_free(devices[i]); // TODO hot reload of video - } + video_background_read(&devices[i], &stop); } } } @@ -181,6 +180,7 @@ static void free_devices(unsigned int video_count) { static void error_callback(int error, const char *description) { log_error("[GLFW] %d: %s", error, description); window_terminate(); + stop = true; exit(EXIT_FAILURE); } @@ -199,7 +199,7 @@ static void key_callback(Window *window, int key, } } -static void loop(bool hr, unsigned int video_count) { +static void loop(bool hr) { if (hr) { hot_reload(); } @@ -208,8 +208,6 @@ static void loop(bool hr, unsigned int video_count) { context.time = window_get_time(); - update_devices(video_count); - if (window_output != NULL) { window_use(window_output, &context); @@ -232,6 +230,8 @@ static void loop(bool hr, unsigned int video_count) { void forge_run(Parameters params) { unsigned int frag_count; + stop = false; + shader_config = config_file_read(params.frag_config_path, false); frag_count = config_file_get_int(shader_config, "FRAG_COUNT", 6); @@ -279,13 +279,19 @@ void forge_run(Parameters params) { timer = timer_init(30); - log_success("Initialized"); + start_devices(params.video_count); + + log_info("Initialized"); while ((window_output == NULL || !window_should_close(window_output)) && (window_monitor == NULL || !window_should_close(window_monitor))) { - loop(params.hot_reload, params.video_count); + loop(params.hot_reload); } + stop = true; + + wait(NULL); + shaders_free(program); if (window_output != NULL) { @@ -302,11 +308,11 @@ void forge_run(Parameters params) { free_devices(params.video_count); - window_terminate(); - free_context(); free_files(frag_count); config_file_free(shader_config); + + window_terminate(); } \ No newline at end of file diff --git a/src/logs.h b/src/logs.h deleted file mode 100644 index fc7c592..0000000 --- a/src/logs.h +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#ifndef LOG_H -#define LOG_H - -#define ANSI_COLOR_RED "\x1b[31m" -#define ANSI_COLOR_GREEN "\x1b[32m" -#define ANSI_COLOR_YELLOW "\x1b[33m" -#define ANSI_COLOR_BLUE "\x1b[34m" -#define ANSI_COLOR_MAGENTA "\x1b[35m" -#define ANSI_COLOR_CYAN "\x1b[36m" -#define ANSI_COLOR_RESET "\x1b[0m" - -#define log_debug(format, ...) \ - fprintf(stderr, ANSI_COLOR_MAGENTA "[DEBG] " format ANSI_COLOR_RESET \ - "\n" __VA_OPT__(, ) __VA_ARGS__) -#define log_success(format, ...) \ - fprintf(stdout, ANSI_COLOR_GREEN "[SUCC] " format ANSI_COLOR_RESET \ - "\n" __VA_OPT__(, ) __VA_ARGS__) -#define log_info(format, ...) \ - fprintf(stdout, "[INFO] " format "\n" __VA_OPT__(, ) __VA_ARGS__) -#define log_warn(format, ...) \ - fprintf(stderr, ANSI_COLOR_YELLOW "[WARN] " format ANSI_COLOR_RESET \ - "\n" __VA_OPT__(, ) __VA_ARGS__) -#define log_error(format, ...) \ - fprintf(stderr, ANSI_COLOR_RED "[FAIL] " format ANSI_COLOR_RESET \ - "\n" __VA_OPT__(, ) __VA_ARGS__) - -#endif /* LOG_H */ \ No newline at end of file diff --git a/src/main.c b/src/main.c index 8ea8c45..5170289 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/rand.c b/src/rand.c index e386c16..b2df3db 100644 --- a/src/rand.c +++ b/src/rand.c @@ -18,14 +18,6 @@ void set_seed(unsigned long long seed) { (void)rand(); } -unsigned char rand_uchar(const unsigned int max) { - return max == 0 ? 0 : (unsigned char)(rand() % max); -} - -unsigned short rand_ushort(const unsigned int max) { - return max == 0 ? 0 : (unsigned short)(rand() % max); -} - unsigned int rand_uint(const unsigned int max) { return max == 0 ? 0 : (unsigned int)(rand() % max); } \ No newline at end of file diff --git a/src/rand.h b/src/rand.h index 8de4d70..33d1dbb 100644 --- a/src/rand.h +++ b/src/rand.h @@ -2,8 +2,6 @@ #define RAND_H void set_seed(unsigned long long seed); -unsigned char rand_uchar(unsigned int max); -unsigned short rand_ushort(unsigned int max); unsigned int rand_uint(unsigned int max); #endif \ No newline at end of file diff --git a/src/shaders.c b/src/shaders.c index d8fbea9..f455bb2 100644 --- a/src/shaders.c +++ b/src/shaders.c @@ -1,11 +1,11 @@ #include +#include #include #include #include #include "config_file.h" #include "constants.h" -#include "logs.h" #include "shaders.h" #include "types.h" @@ -59,7 +59,7 @@ static void init_textures(ShaderProgram *program, Context context) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - log_success("Texture %d initialized", i); + log_info("Texture %d initialized", i); } } @@ -110,7 +110,7 @@ static void link_video_to_texture(ShaderProgram *program, VideoDevice *device, glEGLImageTargetTextureStorageEXT(program->textures[texture_index], (GLeglImageOES)device->dma_image, NULL); - log_success("Texture %d linked to %s", texture_index, device->name); + log_info("Texture %d linked to %s", texture_index, device->name); } static void init_videos(ShaderProgram *program, ConfigFile shader_config, @@ -162,7 +162,7 @@ static void init_framebuffers(ShaderProgram *program, return; } - log_success("Framebuffer %d initialized", i); + log_info("Framebuffer %d initialized", i); } return; @@ -211,7 +211,7 @@ static bool compile_shader(GLuint shader_id, char *name, char *source_code) { if (status_params == GL_FALSE) { log_error("Failed to compile\n%s", log); } else { - log_success("Compilation successful"); + log_info("Compilation successful"); } return status_params == GL_TRUE; @@ -315,7 +315,7 @@ static void init_single_program(ShaderProgram *program, unsigned int i, program->vpos_locations[i] = glGetAttribLocation(program->programs[i], "vPos"); - log_success("Program %d initialized", i + 1); + log_info("Program %d initialized", i + 1); } static void init_programs(ShaderProgram *program, ConfigFile shader_config) { @@ -401,7 +401,7 @@ void shaders_update(ShaderProgram program, File *fragment_shaders, if (result) { glLinkProgram(program.programs[i]); - log_success("Program %d updated", i + 1); + log_info("Program %d updated", i + 1); } } diff --git a/src/video.c b/src/video.c index db85cb8..3604709 100644 --- a/src/video.c +++ b/src/video.c @@ -1,12 +1,14 @@ #include #include #include +#include +#include #include #include -#include "logs.h" #include "types.h" #include "video.h" +#include "window.h" static void ioctl_error(VideoDevice *device, const char *operation, const char *default_msg) { @@ -238,7 +240,7 @@ VideoDevice video_init(char *name, unsigned int preferred_width, return device; } -bool video_read(VideoDevice *device) { +static bool read_video(VideoDevice *device) { if (ioctl(device->fd, VIDIOC_DQBUF, &device->buf) == -1) { ioctl_error(device, "VIDIOC_DQBUF", "buffer type not supported or no buffer allocated or the index " @@ -256,6 +258,25 @@ bool video_read(VideoDevice *device) { return true; } +void video_background_read(VideoDevice *device, bool *stop) { + pid_t pid; + pid = fork(); + if (pid < 0) { + log_error("Could not create subprocess"); + return; + } + if (pid == 0) { + return; + } + log_info("%s background acquisition started (pid: %d)", device->name, pid); + while (!*stop && read_video(device)) { + // repeat infinitely + } + log_info("%s background acquisition stopped (pid: %d)", device->name, pid); + window_terminate(); + exit(EXIT_SUCCESS); +} + void video_free(VideoDevice device) { if (!device.error) { close_stream(device); diff --git a/src/video.h b/src/video.h index c04784a..9298ee3 100644 --- a/src/video.h +++ b/src/video.h @@ -6,7 +6,7 @@ VideoDevice video_init(char *name, unsigned int preferred_width, unsigned int preferred_height); -bool video_read(VideoDevice *device); +void video_background_read(VideoDevice *device, bool *stop); void video_free(VideoDevice device); diff --git a/src/window.c b/src/window.c index ca7215b..eade307 100644 --- a/src/window.c +++ b/src/window.c @@ -1,9 +1,8 @@ #include -#include +#include #include #include -#include "logs.h" #include "types.h" #include "window.h" @@ -22,7 +21,7 @@ static void init_glfw(void (*error_callback)(int, const char *)) { exit(EXIT_FAILURE); } - log_success("[GLFS] Initialized..."); + log_info("[GLFS] Initialized..."); } static GLFWmonitor *get_monitor(unsigned char monitor_index) { @@ -76,7 +75,7 @@ create_window(GLFWmonitor *monitor, char *title, Window *shared_context, // hide cursor glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); - log_success("[GLFW] Window created"); + log_info("[GLFW] Window created"); return window; }