From eb1cc8d07613a7ccc8e6c6c0df8671bc814f6a6f Mon Sep 17 00:00:00 2001 From: Chip Bradford Date: Thu, 11 Aug 2022 18:01:29 -0700 Subject: [PATCH] libobs: Fix gpu thread termination when additional video mixes are added --- libobs/obs-internal.h | 6 +++--- libobs/obs-video.c | 9 +++++---- libobs/obs-view.c | 15 +++++++-------- libobs/obs.c | 28 +++++++++++++++++++++------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 32effee37..9e6c5a76d 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -294,8 +294,8 @@ struct obs_core_video_mix { enum obs_scale_type scale_type; }; -extern int obs_init_video_mix(struct obs_video_info *ovi, - struct obs_core_video_mix *video); +extern struct obs_core_video_mix * +obs_create_video_mix(struct obs_video_info *ovi); extern void obs_free_video_mix(struct obs_core_video_mix *video); struct obs_core_video { @@ -345,7 +345,7 @@ struct obs_core_video { struct circlebuf tasks; pthread_mutex_t mixes_mutex; - DARRAY(struct obs_core_video_mix) mixes; + DARRAY(struct obs_core_video_mix *) mixes; struct obs_core_video_mix *main_mix; }; diff --git a/libobs/obs-video.c b/libobs/obs-video.c index 2584ed9be..6592c4013 100644 --- a/libobs/obs-video.c +++ b/libobs/obs-video.c @@ -828,7 +828,7 @@ static inline void video_sleep(struct obs_core_video *video, uint64_t *p_time, pthread_mutex_lock(&obs->video.mixes_mutex); for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) { - struct obs_core_video_mix *video = obs->video.mixes.array + i; + struct obs_core_video_mix *video = obs->video.mixes.array[i]; bool raw_active = video->raw_was_active; bool gpu_active = video->gpu_was_active; @@ -902,10 +902,11 @@ static inline void output_frames(void) { pthread_mutex_lock(&obs->video.mixes_mutex); for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) { - struct obs_core_video_mix *mix = obs->video.mixes.array + i; + struct obs_core_video_mix *mix = obs->video.mixes.array[i]; if (mix->view) { output_frame(mix); } else { + obs->video.mixes.array[i] = NULL; obs_free_video_mix(mix); da_erase(obs->video.mixes, i); i--; @@ -1075,7 +1076,7 @@ static inline void update_active_states(void) { pthread_mutex_lock(&obs->video.mixes_mutex); for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) - update_active_state(obs->video.mixes.array + i); + update_active_state(obs->video.mixes.array[i]); pthread_mutex_unlock(&obs->video.mixes_mutex); } @@ -1085,7 +1086,7 @@ static inline bool stop_requested(void) pthread_mutex_lock(&obs->video.mixes_mutex); for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) - if (!video_output_stopped(obs->video.mixes.array[i].video)) + if (!video_output_stopped(obs->video.mixes.array[i]->video)) success = false; pthread_mutex_unlock(&obs->video.mixes_mutex); diff --git a/libobs/obs-view.c b/libobs/obs-view.c index d2092d9fd..9fd29d4bd 100644 --- a/libobs/obs-view.c +++ b/libobs/obs-view.c @@ -143,7 +143,7 @@ void obs_view_render(obs_view_t *view) static inline size_t find_mix_for_view(obs_view_t *view) { for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) { - if (obs->video.mixes.array[i].view == view) + if (obs->video.mixes.array[i]->view == view) return i; } @@ -156,25 +156,24 @@ static inline void set_main_mix() struct obs_core_video_mix *mix = NULL; if (idx != DARRAY_INVALID) - mix = obs->video.mixes.array + idx; + mix = obs->video.mixes.array[idx]; obs->video.main_mix = mix; } video_t *obs_view_add(obs_view_t *view) { - struct obs_core_video_mix mix = {0}; - mix.view = view; - if (obs_init_video_mix(&obs->video.ovi, &mix) != 0) { - obs_free_video_mix(&mix); + struct obs_core_video_mix *mix = obs_create_video_mix(&obs->video.ovi); + if (!mix) { return NULL; } + mix->view = view; pthread_mutex_lock(&obs->video.mixes_mutex); da_push_back(obs->video.mixes, &mix); set_main_mix(); pthread_mutex_unlock(&obs->video.mixes_mutex); - return mix.video; + return mix->video; } void obs_view_remove(obs_view_t *view) @@ -182,7 +181,7 @@ void obs_view_remove(obs_view_t *view) pthread_mutex_lock(&obs->video.mixes_mutex); size_t idx = find_mix_for_view(view); if (idx != DARRAY_INVALID) - obs->video.mixes.array[idx].view = NULL; + obs->video.mixes.array[idx]->view = NULL; set_main_mix(); pthread_mutex_unlock(&obs->video.mixes_mutex); } diff --git a/libobs/obs.c b/libobs/obs.c index 95223f464..4baf39a97 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -578,8 +578,8 @@ static inline void set_video_matrix(struct obs_core_video_mix *video, memcpy(video->color_matrix, &mat, sizeof(float) * 16); } -int obs_init_video_mix(struct obs_video_info *ovi, - struct obs_core_video_mix *video) +static int obs_init_video_mix(struct obs_video_info *ovi, + struct obs_core_video_mix *video) { struct video_output_info vi; @@ -620,6 +620,17 @@ int obs_init_video_mix(struct obs_video_info *ovi, return OBS_VIDEO_SUCCESS; } +struct obs_core_video_mix *obs_create_video_mix(struct obs_video_info *ovi) +{ + struct obs_core_video_mix *video = + bzalloc(sizeof(struct obs_core_video_mix)); + if (obs_init_video_mix(ovi, video) != OBS_VIDEO_SUCCESS) { + bfree(video); + video = NULL; + } + return video; +} + static int obs_init_video(struct obs_video_info *ovi) { struct obs_core_video *video = &obs->video; @@ -659,7 +670,7 @@ static void stop_video(void) { pthread_mutex_lock(&obs->video.mixes_mutex); for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) - video_output_stop(obs->video.mixes.array[i].video); + video_output_stop(obs->video.mixes.array[i]->video); pthread_mutex_unlock(&obs->video.mixes_mutex); struct obs_core_video *video = &obs->video; @@ -748,6 +759,7 @@ void obs_free_video_mix(struct obs_core_video_mix *video) video->gpu_encoder_active = 0; video->cur_texture = 0; } + bfree(video); } static void obs_free_video(void) @@ -756,8 +768,10 @@ static void obs_free_video(void) size_t num = obs->video.mixes.num; if (num) blog(LOG_WARNING, "%d views remain at shutdown", num); - for (size_t i = 0; i < num; i++) - obs_free_video_mix(obs->video.mixes.array + i); + for (size_t i = 0; i < num; i++) { + obs_free_video_mix(obs->video.mixes.array[i]); + obs->video.mixes.array[i] = NULL; + } pthread_mutex_unlock(&obs->video.mixes_mutex); pthread_mutex_destroy(&obs->video.mixes_mutex); @@ -2715,7 +2729,7 @@ struct obs_core_video_mix *get_mix_for_video(video_t *v) pthread_mutex_lock(&obs->video.mixes_mutex); for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) { - struct obs_core_video_mix *mix = obs->video.mixes.array + i; + struct obs_core_video_mix *mix = obs->video.mixes.array[i]; if (v == mix->video) { result = mix; @@ -2866,7 +2880,7 @@ bool obs_video_active(void) pthread_mutex_lock(&obs->video.mixes_mutex); for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) { - struct obs_core_video_mix *video = obs->video.mixes.array + i; + struct obs_core_video_mix *video = obs->video.mixes.array[i]; if (os_atomic_load_long(&video->raw_active) > 0 || os_atomic_load_long(&video->gpu_encoder_active) > 0) {