libobs: Fix gpu thread termination when additional video mixes are added

master
Chip Bradford 2022-08-11 18:01:29 -07:00 committed by Jim
parent e7ebe99049
commit eb1cc8d076
4 changed files with 36 additions and 22 deletions

View File

@ -294,8 +294,8 @@ struct obs_core_video_mix {
enum obs_scale_type scale_type; enum obs_scale_type scale_type;
}; };
extern int obs_init_video_mix(struct obs_video_info *ovi, extern struct obs_core_video_mix *
struct obs_core_video_mix *video); obs_create_video_mix(struct obs_video_info *ovi);
extern void obs_free_video_mix(struct obs_core_video_mix *video); extern void obs_free_video_mix(struct obs_core_video_mix *video);
struct obs_core_video { struct obs_core_video {
@ -345,7 +345,7 @@ struct obs_core_video {
struct circlebuf tasks; struct circlebuf tasks;
pthread_mutex_t mixes_mutex; 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; struct obs_core_video_mix *main_mix;
}; };

View File

@ -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); pthread_mutex_lock(&obs->video.mixes_mutex);
for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) { 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 raw_active = video->raw_was_active;
bool gpu_active = video->gpu_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); pthread_mutex_lock(&obs->video.mixes_mutex);
for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) { 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) { if (mix->view) {
output_frame(mix); output_frame(mix);
} else { } else {
obs->video.mixes.array[i] = NULL;
obs_free_video_mix(mix); obs_free_video_mix(mix);
da_erase(obs->video.mixes, i); da_erase(obs->video.mixes, i);
i--; i--;
@ -1075,7 +1076,7 @@ static inline void update_active_states(void)
{ {
pthread_mutex_lock(&obs->video.mixes_mutex); pthread_mutex_lock(&obs->video.mixes_mutex);
for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) 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); pthread_mutex_unlock(&obs->video.mixes_mutex);
} }
@ -1085,7 +1086,7 @@ static inline bool stop_requested(void)
pthread_mutex_lock(&obs->video.mixes_mutex); pthread_mutex_lock(&obs->video.mixes_mutex);
for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) 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; success = false;
pthread_mutex_unlock(&obs->video.mixes_mutex); pthread_mutex_unlock(&obs->video.mixes_mutex);

View File

@ -143,7 +143,7 @@ void obs_view_render(obs_view_t *view)
static inline size_t find_mix_for_view(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++) { 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; return i;
} }
@ -156,25 +156,24 @@ static inline void set_main_mix()
struct obs_core_video_mix *mix = NULL; struct obs_core_video_mix *mix = NULL;
if (idx != DARRAY_INVALID) if (idx != DARRAY_INVALID)
mix = obs->video.mixes.array + idx; mix = obs->video.mixes.array[idx];
obs->video.main_mix = mix; obs->video.main_mix = mix;
} }
video_t *obs_view_add(obs_view_t *view) video_t *obs_view_add(obs_view_t *view)
{ {
struct obs_core_video_mix mix = {0}; struct obs_core_video_mix *mix = obs_create_video_mix(&obs->video.ovi);
mix.view = view; if (!mix) {
if (obs_init_video_mix(&obs->video.ovi, &mix) != 0) {
obs_free_video_mix(&mix);
return NULL; return NULL;
} }
mix->view = view;
pthread_mutex_lock(&obs->video.mixes_mutex); pthread_mutex_lock(&obs->video.mixes_mutex);
da_push_back(obs->video.mixes, &mix); da_push_back(obs->video.mixes, &mix);
set_main_mix(); set_main_mix();
pthread_mutex_unlock(&obs->video.mixes_mutex); pthread_mutex_unlock(&obs->video.mixes_mutex);
return mix.video; return mix->video;
} }
void obs_view_remove(obs_view_t *view) 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); pthread_mutex_lock(&obs->video.mixes_mutex);
size_t idx = find_mix_for_view(view); size_t idx = find_mix_for_view(view);
if (idx != DARRAY_INVALID) if (idx != DARRAY_INVALID)
obs->video.mixes.array[idx].view = NULL; obs->video.mixes.array[idx]->view = NULL;
set_main_mix(); set_main_mix();
pthread_mutex_unlock(&obs->video.mixes_mutex); pthread_mutex_unlock(&obs->video.mixes_mutex);
} }

View File

@ -578,8 +578,8 @@ static inline void set_video_matrix(struct obs_core_video_mix *video,
memcpy(video->color_matrix, &mat, sizeof(float) * 16); memcpy(video->color_matrix, &mat, sizeof(float) * 16);
} }
int obs_init_video_mix(struct obs_video_info *ovi, static int obs_init_video_mix(struct obs_video_info *ovi,
struct obs_core_video_mix *video) struct obs_core_video_mix *video)
{ {
struct video_output_info vi; struct video_output_info vi;
@ -620,6 +620,17 @@ int obs_init_video_mix(struct obs_video_info *ovi,
return OBS_VIDEO_SUCCESS; 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) static int obs_init_video(struct obs_video_info *ovi)
{ {
struct obs_core_video *video = &obs->video; struct obs_core_video *video = &obs->video;
@ -659,7 +670,7 @@ static void stop_video(void)
{ {
pthread_mutex_lock(&obs->video.mixes_mutex); pthread_mutex_lock(&obs->video.mixes_mutex);
for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) 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); pthread_mutex_unlock(&obs->video.mixes_mutex);
struct obs_core_video *video = &obs->video; 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->gpu_encoder_active = 0;
video->cur_texture = 0; video->cur_texture = 0;
} }
bfree(video);
} }
static void obs_free_video(void) static void obs_free_video(void)
@ -756,8 +768,10 @@ static void obs_free_video(void)
size_t num = obs->video.mixes.num; size_t num = obs->video.mixes.num;
if (num) if (num)
blog(LOG_WARNING, "%d views remain at shutdown", num); blog(LOG_WARNING, "%d views remain at shutdown", num);
for (size_t i = 0; i < num; i++) for (size_t i = 0; i < num; i++) {
obs_free_video_mix(obs->video.mixes.array + 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_unlock(&obs->video.mixes_mutex);
pthread_mutex_destroy(&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); pthread_mutex_lock(&obs->video.mixes_mutex);
for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) { 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) { if (v == mix->video) {
result = mix; result = mix;
@ -2866,7 +2880,7 @@ bool obs_video_active(void)
pthread_mutex_lock(&obs->video.mixes_mutex); pthread_mutex_lock(&obs->video.mixes_mutex);
for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) { 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 || if (os_atomic_load_long(&video->raw_active) > 0 ||
os_atomic_load_long(&video->gpu_encoder_active) > 0) { os_atomic_load_long(&video->gpu_encoder_active) > 0) {