浏览代码

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

Chip Bradford 3 年之前
父节点
当前提交
eb1cc8d076
共有 4 个文件被更改,包括 36 次插入22 次删除
  1. 3 3
      libobs/obs-internal.h
  2. 5 4
      libobs/obs-video.c
  3. 7 8
      libobs/obs-view.c
  4. 21 7
      libobs/obs.c

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

+ 5 - 4
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);
 

+ 7 - 8
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);
 }

+ 21 - 7
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) {