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;
};
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;
};

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);
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);

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)
{
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);
}

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);
}
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) {