summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGhostNaN <GhostNaN@protonmail.com>2022-02-22 13:07:42 -0500
committerGhostNaN <GhostNaN@protonmail.com>2022-02-22 13:16:23 -0500
commit50c0c8def6d96bb2f992fad6c77b86fa85e1a596 (patch)
tree25ff4fbfa3194ef8a9d740b3cdb9199b42c12751
parentff398978941f95b5d1e424e26e8b7498e8176205 (diff)
Fixed mpv events, cleanup, and more
This commit mainly fixes how mpv events are processed. See: https://github.com/GhostNaN/mpvpaper/pull/19 - Since some mpv event are deprecated, "mpv_observe_property" is being used instead of MPV_EVENT_PAUSE and MPV_EVENT_UNPAUSE - mpv's default "idle" option for libmpv is now always set to off/no as it provided no use and can't be loaded before user options, sorry. - Pausing functions should now behave a little better with less race conditions. - Cleaning up mpvpaper has been improved by also fixing some race conditions. - Turned some mpv_command_async calls into mpv_command as it was not necessary. - Some error messages have been modified/created - Stopped creating a pthread for a watch list if the file is empty - Add signal handlers for SIGQUIT and SIGTERM to exit mpvpaper
-rw-r--r--src/main.c91
1 files changed, 62 insertions, 29 deletions
diff --git a/src/main.c b/src/main.c
index d823e22..3cb0eb3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -76,7 +76,7 @@ static struct {
} halt_info = {NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0};
-static pthread_t threads[5];
+static pthread_t threads[5] = {0};
static uint SLIDESHOW_TIME = 0;
static bool VERBOSE = 0;
@@ -90,12 +90,6 @@ static void exit_cleanup() {
pthread_cancel(threads[i]);
}
- // Give mpv a chance to finish
- halt_info.kill_render_loop = 1;
- for (int trys=10; halt_info.kill_render_loop && trys > 0; trys--) {
- usleep(10000);
- }
-
if (mpv_glcontext)
mpv_render_context_free(mpv_glcontext);
if (mpv)
@@ -162,6 +156,10 @@ static void frame_handle_done(void *data, struct wl_callback *callback, uint32_t
while (halt_info.is_paused) {
if (time(NULL) - start_time >= 1)
break;
+ if (halt_info.kill_render_loop) {
+ halt_info.kill_render_loop = 0;
+ exit_mpvpaper(0);
+ }
usleep(1000);
}
}
@@ -169,8 +167,10 @@ static void frame_handle_done(void *data, struct wl_callback *callback, uint32_t
// Render next frame
if (!halt_info.kill_render_loop)
render(data);
- else
+ else {
halt_info.kill_render_loop = 0;
+ exit_mpvpaper(0);
+ }
}
const static struct wl_callback_listener wl_surface_frame_listener = {
@@ -266,7 +266,8 @@ static void *monitor_pauselist() {
}
if (is_paused) {
is_paused = 0;
- halt_info.is_paused -= 1;
+ if (halt_info.is_paused)
+ halt_info.is_paused -= 1;
}
}
pthread_sleep(1);
@@ -311,7 +312,8 @@ static void *handle_auto_pause() {
}
if (is_paused) {
is_paused = 0;
- halt_info.is_paused -= 1;
+ if (halt_info.is_paused)
+ halt_info.is_paused -= 1;
}
}
pthread_sleep(1);
@@ -346,6 +348,9 @@ static void *handle_mpv_events() {
bool mpv_paused = 0;
time_t start_time = time(NULL);
+ const int MPV_OBSERVE_PAUSE = 1;
+ mpv_observe_property(mpv, MPV_OBSERVE_PAUSE, "pause", MPV_FORMAT_FLAG);
+
while (!halt_info.kill_render_loop) {
if (SLIDESHOW_TIME) {
if ((time(NULL) - start_time) >= SLIDESHOW_TIME) {
@@ -355,17 +360,31 @@ static void *handle_mpv_events() {
}
mpv_event* event = mpv_wait_event(mpv, 0);
- if (event->event_id == MPV_EVENT_SHUTDOWN || event->event_id == MPV_EVENT_IDLE)
- exit_mpvpaper(0);
- else if (event->event_id == MPV_EVENT_PAUSE) {
- mpv_paused = 1;
- // User paused
- if (!halt_info.is_paused)
- halt_info.is_paused += 1;
+
+ if (event->event_id == MPV_EVENT_SHUTDOWN) {
+ // Give mpv a chance to finish
+ halt_info.kill_render_loop = 1;
+ for (int trys=10; halt_info.kill_render_loop && trys > 0; trys--) {
+ usleep(10000);
+ }
+ // render loop didn't kill itself, this may cause crashing
+ if (halt_info.kill_render_loop) {
+ if (VERBOSE)
+ cflp_warning("Failed to quit mpv");
+ exit_mpvpaper(0);
+ }
}
- else if (event->event_id == MPV_EVENT_UNPAUSE) {
- mpv_paused = 0;
- halt_info.is_paused = 0;
+ else if (event->event_id == MPV_EVENT_PROPERTY_CHANGE) {
+ if (event->reply_userdata == MPV_OBSERVE_PAUSE) {
+ mpv_get_property(mpv, "pause", MPV_FORMAT_FLAG, &mpv_paused);
+ if (mpv_paused) {
+ // User paused
+ if (!halt_info.is_paused)
+ halt_info.is_paused += 1;
+ } else {
+ halt_info.is_paused = 0;
+ }
+ }
}
if (!halt_info.is_paused && mpv_paused) {
@@ -374,6 +393,9 @@ static void *handle_mpv_events() {
pthread_usleep(10000);
}
+
+ mpv_unobserve_property(mpv, MPV_OBSERVE_PAUSE);
+
pthread_exit(NULL);
}
@@ -458,8 +480,9 @@ static void init_mpv(struct display_output *output) {
set_init_mpv_options();
- if (mpv_initialize(mpv) < 0) {
- cflp_error("mpv init failed");
+ int err = mpv_initialize(mpv);
+ if (err < 0) {
+ cflp_error("Failed to init mpv, %s", mpv_error_string(err));
exit_mpvpaper(1);
}
@@ -491,12 +514,12 @@ static void init_mpv(struct display_output *output) {
// Save default start pos
default_start = mpv_get_property_string(mpv, "start");
// Restore video position
- mpv_command_async(mpv, 0, (const char*[]) {"set", "start", time_pos, NULL});
+ mpv_command(mpv, (const char*[]) {"set", "start", time_pos, NULL});
// Recover playlist pos, that is if it's not shuffled...
- mpv_command_async(mpv, 0, (const char*[]) {"set", "playlist-start", playlist_pos, NULL});
+ mpv_command(mpv, (const char*[]) {"set", "playlist-start", playlist_pos, NULL});
}
- mpv_command_async(mpv, 0, (const char*[]) {"loadfile", video_path, NULL});
+ mpv_command(mpv, (const char*[]) {"loadfile", video_path, NULL});
mpv_event* event = mpv_wait_event(mpv, 1);
while (event->event_id != MPV_EVENT_FILE_LOADED){
@@ -507,7 +530,10 @@ static void init_mpv(struct display_output *output) {
// Return start pos to default
if (default_start)
- mpv_command_async(mpv, 0, (const char*[]) {"set", "start", default_start, NULL});
+ mpv_command(mpv, (const char*[]) {"set", "start", default_start, NULL});
+
+ // mpv must never idle
+ mpv_command(mpv, (const char*[]) {"set", "idle", "no", NULL});
}
static void init_egl(struct display_output *output) {
@@ -548,7 +574,7 @@ static void init_egl(struct display_output *output) {
egl_context = eglCreateContext(egl_display, config, EGL_NO_CONTEXT, ctx_attrib);
if (egl_context) {
if (VERBOSE) {
- cflp_info("OpenGL %i.%i EGL context loaded", gl_versions[i].major, gl_versions[i].minor);
+ cflp_info("OpenGL %i.%i EGL context created", gl_versions[i].major, gl_versions[i].minor);
}
break;
}
@@ -563,7 +589,10 @@ static void init_egl(struct display_output *output) {
eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
eglSwapInterval(egl_display, 0);
- gladLoadGLLoader((GLADloadproc) eglGetProcAddress);
+ if(!gladLoadGLLoader((GLADloadproc) eglGetProcAddress)) {
+ cflp_error("Failed to load OpenGL");
+ exit_mpvpaper(1);
+ }
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, output->width, output->height);
@@ -767,7 +796,9 @@ static char **get_watch_list(char *path_name) {
}
fclose(file);
- return list;
+ // If any app found
+ if (list[0])
+ return list;
}
return NULL;
}
@@ -923,6 +954,8 @@ static void parse_command_line(int argc, char **argv, struct wl_state *state) {
int main(int argc, char **argv) {
signal(SIGINT, handle_signal);
+ signal(SIGQUIT, handle_signal);
+ signal(SIGTERM, handle_signal);
struct wl_state state = {0};
wl_list_init(&state.outputs);