From 28cba2e2b33c55f69a7752efd490e4ec922e4d06 Mon Sep 17 00:00:00 2001 From: esi Date: Mon, 8 Aug 2022 19:11:33 -0400 Subject: [PATCH] [obs] Allow the client to auto-recover Previously, if the client's subscription to the frame buffer became invalid for any reason, the video feed in OBS would freeze until the user goes in and changes any of the settings. This commit allows the plugin to automatically attempt to recover. --- AUTHORS | 1 + obs/lg.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/AUTHORS b/AUTHORS index 0439e033..b9deafff 100644 --- a/AUTHORS +++ b/AUTHORS @@ -64,3 +64,4 @@ Matthew McMullin (matthewjmc) Leonard Fricke (Leo1998) David Meier (Kenny.ch) Daniel Cordero (0xdc) +esi (esibun) diff --git a/obs/lg.c b/obs/lg.c index 7fbd0546..03a32883 100644 --- a/obs/lg.c +++ b/obs/lg.c @@ -54,7 +54,8 @@ typedef enum STATE_OPEN, STATE_STARTING, STATE_RUNNING, - STATE_STOPPING + STATE_STOPPING, + STATE_RESTARTING } LGState; @@ -107,6 +108,8 @@ typedef struct } LGPlugin; +static void * frameThread(void * data); +static void * pointerThread(void * data); static void lgUpdate(void * data, obs_data_t * settings); static const char * lgGetName(void * unused) @@ -125,6 +128,20 @@ static void * lgCreate(obs_data_t * settings, obs_source_t * context) return this; } +static void createThreads(LGPlugin * this) +{ + pthread_create(&this->frameThread, NULL, frameThread, this); + pthread_setname_np(this->frameThread, "LGFrameThread"); + pthread_create(&this->pointerThread, NULL, pointerThread, this); + pthread_setname_np(this->pointerThread, "LGPointerThread"); +} + +static void waitThreads(LGPlugin * this) +{ + pthread_join(this->frameThread, NULL); + pthread_join(this->pointerThread, NULL); +} + static void deinit(LGPlugin * this) { switch(this->state) @@ -137,9 +154,9 @@ static void deinit(LGPlugin * this) case STATE_RUNNING: case STATE_STOPPING: + case STATE_RESTARTING: this->state = STATE_STOPPING; - pthread_join(this->frameThread , NULL); - pthread_join(this->pointerThread, NULL); + createThreads(this); this->state = STATE_STOPPED; /* fallthrough */ @@ -251,7 +268,7 @@ static void * frameThread(void * data) } lgmpClientUnsubscribe(&this->frameQueue); - this->state = STATE_STOPPING; + this->state = STATE_RESTARTING; return NULL; } @@ -375,7 +392,7 @@ static void * pointerThread(void * data) this->cursorData = NULL; this->cursorSize = 0; - this->state = STATE_STOPPING; + this->state = STATE_RESTARTING; return NULL; } @@ -419,10 +436,7 @@ static void lgUpdate(void * data, obs_data_t * settings) } this->state = STATE_STARTING; - pthread_create(&this->frameThread, NULL, frameThread, this); - pthread_setname_np(this->frameThread, "LGFrameThread"); - pthread_create(&this->pointerThread, NULL, pointerThread, this); - pthread_setname_np(this->pointerThread, "LGPointerThread"); + createThreads(this); } #if LIBOBS_API_MAJOR_VER >= 27 @@ -480,6 +494,12 @@ static void lgVideoTick(void * data, float seconds) { LGPlugin * this = (LGPlugin *)data; + if (this->state == STATE_RESTARTING) { + waitThreads(this); + + this->state = STATE_STARTING; + createThreads(this); + } if (this->state != STATE_RUNNING) return;