feat: video reconnect (wip egl error 3003)
This commit is contained in:
+77
-23
@@ -4,13 +4,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "config_file.h"
|
||||
#include "file.h"
|
||||
#include "forge.h"
|
||||
#include "midi.h"
|
||||
#include "project.h"
|
||||
@@ -22,11 +21,11 @@
|
||||
#include "video.h"
|
||||
#include "window.h"
|
||||
|
||||
static Parameters init_params;
|
||||
static SharedContext *context;
|
||||
static ShaderProgram program;
|
||||
static Window *window_output;
|
||||
static Window *window_monitor;
|
||||
static VideoCaptureArray inputs;
|
||||
static Timer timer;
|
||||
static MidiDevice midi;
|
||||
static bool trace_midi;
|
||||
@@ -66,9 +65,6 @@ static void init_context(const Parameters *params) {
|
||||
params->auto_random_cycle, params->base_tempo, params->load_state);
|
||||
|
||||
memset(context->input_resolutions, 0, sizeof(context->input_resolutions));
|
||||
memset(context->input_formats, 0, sizeof(context->input_formats));
|
||||
memset(context->input_fps, 0, sizeof(context->input_fps));
|
||||
memset(context->input_swap, 0, sizeof(context->input_swap));
|
||||
}
|
||||
|
||||
static void free_context() { shared_close_context(context); }
|
||||
@@ -79,36 +75,79 @@ static void reload_shader(unsigned int i) {
|
||||
|
||||
#ifdef VIDEO_IN
|
||||
static void init_inputs(const StringArray *video_in, unsigned int video_size) {
|
||||
inputs.length = video_in->length;
|
||||
context->inputs.length = video_in->length;
|
||||
|
||||
for (unsigned int i = 0; i < video_in->length; i++) {
|
||||
video_init(&inputs.values[i], video_in->values[i], video_size);
|
||||
video_init(&context->inputs.values[i], video_in->values[i], video_size);
|
||||
|
||||
if (!inputs.values[i].error) {
|
||||
context->input_resolutions[i][0] = inputs.values[i].width;
|
||||
context->input_resolutions[i][1] = inputs.values[i].height;
|
||||
context->input_formats[i] = inputs.values[i].pixelformat;
|
||||
if (!context->inputs.values[i].error) {
|
||||
context->input_resolutions[i][0] = context->inputs.values[i].width;
|
||||
context->input_resolutions[i][1] = context->inputs.values[i].height;
|
||||
context->inputs.values[i].needs_reload = false;
|
||||
context->inputs.values[i].disconnected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool start_video_captures(unsigned int video_count, bool trace_fps) {
|
||||
for (unsigned int i = 0; i < video_count; i++) {
|
||||
if (!inputs.values[i].error &&
|
||||
!video_background_read(&inputs.values[i], context, i, trace_fps)) {
|
||||
return false;
|
||||
static bool reconnect_video_captures(const StringArray *video_in,
|
||||
unsigned int video_size, bool trace_fps) {
|
||||
for (unsigned int i = 0; i < video_in->length; i++) {
|
||||
if (context->inputs.values[i].disconnected) {
|
||||
video_init(&context->inputs.values[i], video_in->values[i], video_size);
|
||||
|
||||
if (!context->inputs.values[i].error) {
|
||||
context->input_resolutions[i][0] = context->inputs.values[i].width;
|
||||
context->input_resolutions[i][1] = context->inputs.values[i].height;
|
||||
|
||||
if (!video_background_read(&context->inputs.values[i], context, i,
|
||||
trace_fps)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
context->inputs.values[i].needs_reload = true;
|
||||
context->inputs.values[i].disconnected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool start_video_captures(unsigned int video_count, bool trace_fps) {
|
||||
pid_t pid;
|
||||
for (unsigned int i = 0; i < video_count; i++) {
|
||||
if (!context->inputs.values[i].error &&
|
||||
!video_background_read(&context->inputs.values[i], context, i,
|
||||
trace_fps)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
log_error("Could not create subprocess");
|
||||
return false;
|
||||
}
|
||||
if (pid == 0) {
|
||||
return true;
|
||||
}
|
||||
log_info("background reconnect acquisition started (pid: %d)", pid);
|
||||
while (!context->stop) {
|
||||
sleep(1);
|
||||
if (!reconnect_video_captures(&init_params.video_in, init_params.video_size,
|
||||
init_params.trace_fps)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void free_video_captures(unsigned int video_count) {
|
||||
for (unsigned int i = 0; i < video_count; i++) {
|
||||
shaders_free_input(&program, &inputs.values[i]);
|
||||
shaders_free_input(&program, i);
|
||||
|
||||
video_free(&inputs.values[i]);
|
||||
video_free(&context->inputs.values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* VIDEO_IN */
|
||||
|
||||
static void error_callback(int error, const char *description) {
|
||||
@@ -140,6 +179,8 @@ static void midi_callback(unsigned char code, unsigned char value) {
|
||||
}
|
||||
|
||||
static bool init(const Parameters *params) {
|
||||
init_params = *params;
|
||||
|
||||
project_init(&project, params->project_path, params->config_file);
|
||||
|
||||
if (project.error) {
|
||||
@@ -200,7 +241,7 @@ static bool init(const Parameters *params) {
|
||||
}
|
||||
|
||||
#ifdef VIDEO_IN
|
||||
shaders_link_inputs(&program, &project, &inputs);
|
||||
shaders_link_inputs(&program, &project, &context->inputs);
|
||||
#endif /* VIDEO_IN */
|
||||
|
||||
if (program.error) {
|
||||
@@ -221,11 +262,20 @@ static bool should_close() {
|
||||
(window_monitor != NULL && window_should_close(window_monitor));
|
||||
}
|
||||
|
||||
static void loop(bool hr, bool trace_fps) {
|
||||
static bool loop(bool hr, bool trace_fps) {
|
||||
if (hr) {
|
||||
project_reload(&project, reload_shader);
|
||||
}
|
||||
|
||||
#ifdef VIDEO_IN
|
||||
for (unsigned int i = 0; i < context->inputs.length; i++) {
|
||||
if (context->inputs.values[i].needs_reload) {
|
||||
shaders_relink_input(&program, &project, &context->inputs, i);
|
||||
context->inputs.values[i].needs_reload = false;
|
||||
}
|
||||
}
|
||||
#endif /* VIDEO_IN */
|
||||
|
||||
compute_fps(trace_fps);
|
||||
|
||||
context->time = window_get_time();
|
||||
@@ -248,6 +298,8 @@ static void loop(bool hr, bool trace_fps) {
|
||||
}
|
||||
|
||||
window_events();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void shutdown(const Parameters *params) {
|
||||
@@ -288,8 +340,10 @@ void forge_run(const Parameters *params) {
|
||||
}
|
||||
|
||||
while (!should_close()) {
|
||||
loop(params->hot_reload, params->trace_fps);
|
||||
if (!loop(params->hot_reload, params->trace_fps)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
shutdown(params);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user