浏览代码

libobs: Use atomics for certain output boolean variables

jp9000 9 年之前
父节点
当前提交
ceb675f6df
共有 3 个文件被更改,包括 78 次插入47 次删除
  1. 4 4
      libobs/obs-internal.h
  2. 14 4
      libobs/obs-output-delay.c
  3. 60 39
      libobs/obs-output.c

+ 4 - 4
libobs/obs-internal.h

@@ -792,7 +792,7 @@ struct obs_output {
 	int                             reconnect_retry_max;
 	int                             reconnect_retry_max;
 	int                             reconnect_retries;
 	int                             reconnect_retries;
 	int                             reconnect_retry_cur_sec;
 	int                             reconnect_retry_cur_sec;
-	bool                            reconnecting;
+	volatile bool                   reconnecting;
 	pthread_t                       reconnect_thread;
 	pthread_t                       reconnect_thread;
 	os_event_t                      *reconnect_stop_event;
 	os_event_t                      *reconnect_stop_event;
 	volatile bool                   reconnect_thread_active;
 	volatile bool                   reconnect_thread_active;
@@ -804,7 +804,7 @@ struct obs_output {
 
 
 	int                             total_frames;
 	int                             total_frames;
 
 
-	bool                            active;
+	volatile bool                   active;
 	volatile bool                   stopped;
 	volatile bool                   stopped;
 	video_t                         *video;
 	video_t                         *video;
 	audio_t                         *audio;
 	audio_t                         *audio;
@@ -831,8 +831,8 @@ struct obs_output {
 	uint32_t                        delay_flags;
 	uint32_t                        delay_flags;
 	uint32_t                        delay_cur_flags;
 	uint32_t                        delay_cur_flags;
 	volatile long                   delay_restart_refs;
 	volatile long                   delay_restart_refs;
-	bool                            delay_active;
-	bool                            delay_capturing;
+	volatile bool                   delay_active;
+	volatile bool                   delay_capturing;
 };
 };
 
 
 static inline void do_output_signal(struct obs_output *output,
 static inline void do_output_signal(struct obs_output *output,

+ 14 - 4
libobs/obs-output-delay.c

@@ -18,6 +18,16 @@
 #include <inttypes.h>
 #include <inttypes.h>
 #include "obs-internal.h"
 #include "obs-internal.h"
 
 
+static inline bool delay_active(const struct obs_output *output)
+{
+	return os_atomic_load_bool(&output->delay_active);
+}
+
+static inline bool delay_capturing(const struct obs_output *output)
+{
+	return os_atomic_load_bool(&output->delay_capturing);
+}
+
 static inline void push_packet(struct obs_output *output,
 static inline void push_packet(struct obs_output *output,
 		struct encoder_packet *packet, uint64_t t)
 		struct encoder_packet *packet, uint64_t t)
 {
 {
@@ -37,7 +47,7 @@ static inline void process_delay_data(struct obs_output *output,
 {
 {
 	switch (dd->msg) {
 	switch (dd->msg) {
 	case DELAY_MSG_PACKET:
 	case DELAY_MSG_PACKET:
-		if (!output->delay_active || !output->delay_capturing)
+		if (!delay_active(output) || !delay_capturing(output))
 			obs_free_encoder_packet(&dd->packet);
 			obs_free_encoder_packet(&dd->packet);
 		else
 		else
 			output->delay_callback(output, &dd->packet);
 			output->delay_callback(output, &dd->packet);
@@ -63,7 +73,7 @@ void obs_output_cleanup_delay(obs_output_t *output)
 	}
 	}
 
 
 	output->active_delay_ns = 0;
 	output->active_delay_ns = 0;
-	output->delay_restart_refs = 0;
+	os_atomic_set_long(&output->delay_restart_refs, 0);
 }
 }
 
 
 static inline bool pop_packet(struct obs_output *output, uint64_t t)
 static inline bool pop_packet(struct obs_output *output, uint64_t t)
@@ -129,7 +139,7 @@ bool obs_output_delay_start(obs_output_t *output)
 		.ts  = os_gettime_ns(),
 		.ts  = os_gettime_ns(),
 	};
 	};
 
 
-	if (!output->delay_active) {
+	if (!delay_active(output)) {
 		bool can_begin = obs_output_can_begin_data_capture(output, 0);
 		bool can_begin = obs_output_can_begin_data_capture(output, 0);
 		if (!can_begin)
 		if (!can_begin)
 			return false;
 			return false;
@@ -141,7 +151,7 @@ bool obs_output_delay_start(obs_output_t *output)
 	circlebuf_push_back(&output->delay_data, &dd, sizeof(dd));
 	circlebuf_push_back(&output->delay_data, &dd, sizeof(dd));
 	pthread_mutex_unlock(&output->delay_mutex);
 	pthread_mutex_unlock(&output->delay_mutex);
 
 
-	if (output->delay_active) {
+	if (delay_active(output)) {
 		os_atomic_inc_long(&output->delay_restart_refs);
 		os_atomic_inc_long(&output->delay_restart_refs);
 		do_output_signal(output, "starting");
 		do_output_signal(output, "starting");
 		return true;
 		return true;

+ 60 - 39
libobs/obs-output.c

@@ -20,6 +20,26 @@
 #include "obs.h"
 #include "obs.h"
 #include "obs-internal.h"
 #include "obs-internal.h"
 
 
+static inline bool active(const struct obs_output *output)
+{
+	return os_atomic_load_bool(&output->active);
+}
+
+static inline bool reconnecting(const struct obs_output *output)
+{
+	return os_atomic_load_bool(&output->reconnecting);
+}
+
+static inline bool delay_active(const struct obs_output *output)
+{
+	return os_atomic_load_bool(&output->delay_active);
+}
+
+static inline bool delay_capturing(const struct obs_output *output)
+{
+	return os_atomic_load_bool(&output->delay_capturing);
+}
+
 static inline void signal_stop(struct obs_output *output, int code);
 static inline void signal_stop(struct obs_output *output, int code);
 
 
 const struct obs_output_info *find_output(const char *id)
 const struct obs_output_info *find_output(const char *id)
@@ -136,7 +156,7 @@ void obs_output_destroy(obs_output_t *output)
 
 
 		blog(LOG_INFO, "output '%s' destroyed", output->context.name);
 		blog(LOG_INFO, "output '%s' destroyed", output->context.name);
 
 
-		if (output->valid && output->active)
+		if (output->valid && active(output))
 			obs_output_actual_stop(output, true);
 			obs_output_actual_stop(output, true);
 		if (output->service)
 		if (output->service)
 			output->service->output = NULL;
 			output->service->output = NULL;
@@ -194,7 +214,7 @@ bool obs_output_actual_start(obs_output_t *output)
 		output->starting_lagged_count = obs->video.lagged_frames;
 		output->starting_lagged_count = obs->video.lagged_frames;
 	}
 	}
 
 
-	if (output->delay_restart_refs)
+	if (os_atomic_load_long(&output->delay_restart_refs))
 		os_atomic_dec_long(&output->delay_restart_refs);
 		os_atomic_dec_long(&output->delay_restart_refs);
 
 
 	return success;
 	return success;
@@ -286,12 +306,13 @@ void obs_output_actual_stop(obs_output_t *output, bool force)
 	if (output->video)
 	if (output->video)
 		log_frame_info(output);
 		log_frame_info(output);
 
 
-	if (output->delay_active && (force || !output->delay_restart_refs)) {
-		output->delay_active = false;
+	if (delay_active(output) &&
+	    (force || !os_atomic_load_long(&output->delay_restart_refs))) {
+		os_atomic_set_bool(&output->delay_active, false);
 		obs_output_end_data_capture(output);
 		obs_output_end_data_capture(output);
 	}
 	}
 
 
-	if (force || !output->delay_active)
+	if (force || !delay_active(output))
 		signal_stop(output, OBS_OUTPUT_SUCCESS);
 		signal_stop(output, OBS_OUTPUT_SUCCESS);
 }
 }
 
 
@@ -321,7 +342,7 @@ void obs_output_force_stop(obs_output_t *output)
 bool obs_output_active(const obs_output_t *output)
 bool obs_output_active(const obs_output_t *output)
 {
 {
 	return (output != NULL) ?
 	return (output != NULL) ?
-		(output->active || output->reconnecting) : false;
+		(active(output) || reconnecting(output)) : false;
 }
 }
 
 
 static inline obs_data_t *get_defaults(const struct obs_output_info *info)
 static inline obs_data_t *get_defaults(const struct obs_output_info *info)
@@ -442,7 +463,7 @@ void obs_output_set_mixer(obs_output_t *output, size_t mixer_idx)
 	if (!obs_output_valid(output, "obs_output_set_mixer"))
 	if (!obs_output_valid(output, "obs_output_set_mixer"))
 		return;
 		return;
 
 
-	if (!output->active)
+	if (!active(output))
 		output->mixer_idx = mixer_idx;
 		output->mixer_idx = mixer_idx;
 }
 }
 
 
@@ -547,7 +568,7 @@ void obs_output_set_service(obs_output_t *output, obs_service_t *service)
 {
 {
 	if (!obs_output_valid(output, "obs_output_set_service"))
 	if (!obs_output_valid(output, "obs_output_set_service"))
 		return;
 		return;
-	if (output->active || !service || service->active)
+	if (active(output) || !service || service->active)
 		return;
 		return;
 
 
 	if (service->output)
 	if (service->output)
@@ -580,7 +601,7 @@ uint64_t obs_output_get_total_bytes(const obs_output_t *output)
 	if (!output->info.get_total_bytes)
 	if (!output->info.get_total_bytes)
 		return 0;
 		return 0;
 
 
-	if (output->delay_active && !output->delay_capturing)
+	if (delay_active(output) && !delay_capturing(output))
 		return 0;
 		return 0;
 
 
 	return output->info.get_total_bytes(output->context.data);
 	return output->info.get_total_bytes(output->context.data);
@@ -610,7 +631,7 @@ void obs_output_set_preferred_size(obs_output_t *output, uint32_t width,
 	if ((output->info.flags & OBS_OUTPUT_VIDEO) == 0)
 	if ((output->info.flags & OBS_OUTPUT_VIDEO) == 0)
 		return;
 		return;
 
 
-	if (output->active) {
+	if (active(output)) {
 		blog(LOG_WARNING, "output '%s': Cannot set the preferred "
 		blog(LOG_WARNING, "output '%s': Cannot set the preferred "
 		                  "resolution while the output is active",
 		                  "resolution while the output is active",
 		                  obs_output_get_name(output));
 		                  obs_output_get_name(output));
@@ -1342,7 +1363,7 @@ static void hook_data_capture(struct obs_output *output, bool encoded,
 			output->delay_cur_flags = output->delay_flags;
 			output->delay_cur_flags = output->delay_flags;
 			output->delay_callback = encoded_callback;
 			output->delay_callback = encoded_callback;
 			encoded_callback = process_delay;
 			encoded_callback = process_delay;
-			output->delay_active = true;
+			os_atomic_set_bool(&output->delay_active, true);
 
 
 			blog(LOG_INFO, "Output '%s': %"PRIu32" second delay "
 			blog(LOG_INFO, "Output '%s': %"PRIu32" second delay "
 			               "active, preserve on disconnect is %s",
 			               "active, preserve on disconnect is %s",
@@ -1424,8 +1445,8 @@ bool obs_output_can_begin_data_capture(const obs_output_t *output,
 	if (!obs_output_valid(output, "obs_output_can_begin_data_capture"))
 	if (!obs_output_valid(output, "obs_output_can_begin_data_capture"))
 		return false;
 		return false;
 
 
-	if (output->delay_active) return true;
-	if (output->active) return false;
+	if (delay_active(output)) return true;
+	if (active(output)) return false;
 
 
 	convert_flags(output, flags, &encoded, &has_video, &has_audio,
 	convert_flags(output, flags, &encoded, &has_video, &has_audio,
 			&has_service);
 			&has_service);
@@ -1492,7 +1513,7 @@ bool obs_output_initialize_encoders(obs_output_t *output, uint32_t flags)
 	if (!obs_output_valid(output, "obs_output_initialize_encoders"))
 	if (!obs_output_valid(output, "obs_output_initialize_encoders"))
 		return false;
 		return false;
 
 
-	if (output->active) return output->delay_active;
+	if (active(output)) return delay_active(output);
 
 
 	convert_flags(output, flags, &encoded, &has_video, &has_audio,
 	convert_flags(output, flags, &encoded, &has_video, &has_audio,
 			&has_service);
 			&has_service);
@@ -1514,17 +1535,17 @@ bool obs_output_initialize_encoders(obs_output_t *output, uint32_t flags)
 
 
 static bool begin_delayed_capture(obs_output_t *output)
 static bool begin_delayed_capture(obs_output_t *output)
 {
 {
-	if (output->delay_capturing)
+	if (delay_capturing(output))
 		return false;
 		return false;
 
 
 	pthread_mutex_lock(&output->interleaved_mutex);
 	pthread_mutex_lock(&output->interleaved_mutex);
 	reset_packet_data(output);
 	reset_packet_data(output);
-	output->delay_capturing = true;
+	os_atomic_set_bool(&output->delay_capturing, true);
 	pthread_mutex_unlock(&output->interleaved_mutex);
 	pthread_mutex_unlock(&output->interleaved_mutex);
 
 
-	if (output->reconnecting) {
+	if (reconnecting(output)) {
 		signal_reconnect_success(output);
 		signal_reconnect_success(output);
-		output->reconnecting = false;
+		os_atomic_set_bool(&output->reconnecting, false);
 	} else {
 	} else {
 		signal_start(output);
 		signal_start(output);
 	}
 	}
@@ -1539,8 +1560,8 @@ bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags)
 	if (!obs_output_valid(output, "obs_output_begin_data_capture"))
 	if (!obs_output_valid(output, "obs_output_begin_data_capture"))
 		return false;
 		return false;
 
 
-	if (output->delay_active) return begin_delayed_capture(output);
-	if (output->active) return false;
+	if (delay_active(output)) return begin_delayed_capture(output);
+	if (active(output)) return false;
 
 
 	output->total_frames   = 0;
 	output->total_frames   = 0;
 
 
@@ -1557,13 +1578,13 @@ bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags)
 		obs_service_activate(output->service);
 		obs_service_activate(output->service);
 
 
 	do_output_signal(output, "activate");
 	do_output_signal(output, "activate");
-	output->active = true;
+	os_atomic_set_bool(&output->active, true);
 
 
-	if (output->reconnecting) {
+	if (reconnecting(output)) {
 		signal_reconnect_success(output);
 		signal_reconnect_success(output);
-		output->reconnecting = false;
+		os_atomic_set_bool(&output->reconnecting, false);
 
 
-	} else if (output->delay_active) {
+	} else if (delay_active(output)) {
 		do_output_signal(output, "starting");
 		do_output_signal(output, "starting");
 
 
 	} else {
 	} else {
@@ -1592,12 +1613,12 @@ void obs_output_end_data_capture(obs_output_t *output)
 	if (!obs_output_valid(output, "obs_output_end_data_capture"))
 	if (!obs_output_valid(output, "obs_output_end_data_capture"))
 		return;
 		return;
 
 
-	if (output->delay_active) {
-		output->delay_capturing = false;
+	if (delay_active(output)) {
+		os_atomic_set_bool(&output->delay_capturing, false);
 		return;
 		return;
 	}
 	}
 
 
-	if (!output->active) return;
+	if (!active(output)) return;
 
 
 	convert_flags(output, 0, &encoded, &has_video, &has_audio,
 	convert_flags(output, 0, &encoded, &has_video, &has_audio,
 			&has_service);
 			&has_service);
@@ -1631,7 +1652,7 @@ void obs_output_end_data_capture(obs_output_t *output)
 		obs_output_cleanup_delay(output);
 		obs_output_cleanup_delay(output);
 
 
 	do_output_signal(output, "deactivate");
 	do_output_signal(output, "deactivate");
-	output->active = false;
+	os_atomic_set_bool(&output->active, false);
 }
 }
 
 
 static void *reconnect_thread(void *param)
 static void *reconnect_thread(void *param)
@@ -1647,7 +1668,7 @@ static void *reconnect_thread(void *param)
 	if (os_event_try(output->reconnect_stop_event) == EAGAIN)
 	if (os_event_try(output->reconnect_stop_event) == EAGAIN)
 		pthread_detach(output->reconnect_thread);
 		pthread_detach(output->reconnect_thread);
 	else
 	else
-		output->reconnecting = false;
+		os_atomic_set_bool(&output->reconnecting, false);
 
 
 	output->reconnect_thread_active = false;
 	output->reconnect_thread_active = false;
 	return NULL;
 	return NULL;
@@ -1657,23 +1678,23 @@ static void output_reconnect(struct obs_output *output)
 {
 {
 	int ret;
 	int ret;
 
 
-	if (!output->reconnecting) {
+	if (!reconnecting(output)) {
 		output->reconnect_retry_cur_sec = output->reconnect_retry_sec;
 		output->reconnect_retry_cur_sec = output->reconnect_retry_sec;
 		output->reconnect_retries = 0;
 		output->reconnect_retries = 0;
 	}
 	}
 
 
 	if (output->reconnect_retries >= output->reconnect_retry_max) {
 	if (output->reconnect_retries >= output->reconnect_retry_max) {
-		output->reconnecting = false;
-		if (output->delay_active) {
-			output->delay_active = false;
+		os_atomic_set_bool(&output->reconnecting, false);
+		if (delay_active(output)) {
+			os_atomic_set_bool(&output->delay_active, false);
 			obs_output_end_data_capture(output);
 			obs_output_end_data_capture(output);
 		}
 		}
 		signal_stop(output, OBS_OUTPUT_DISCONNECTED);
 		signal_stop(output, OBS_OUTPUT_DISCONNECTED);
 		return;
 		return;
 	}
 	}
 
 
-	if (!output->reconnecting) {
-		output->reconnecting = true;
+	if (!reconnecting(output)) {
+		os_atomic_set_bool(&output->reconnecting, true);
 		os_event_reset(output->reconnect_stop_event);
 		os_event_reset(output->reconnect_stop_event);
 	}
 	}
 
 
@@ -1687,7 +1708,7 @@ static void output_reconnect(struct obs_output *output)
 			&reconnect_thread, output);
 			&reconnect_thread, output);
 	if (ret < 0) {
 	if (ret < 0) {
 		blog(LOG_WARNING, "Failed to create reconnect thread");
 		blog(LOG_WARNING, "Failed to create reconnect thread");
-		output->reconnecting = false;
+		os_atomic_set_bool(&output->reconnecting, false);
 		signal_stop(output, OBS_OUTPUT_DISCONNECTED);
 		signal_stop(output, OBS_OUTPUT_DISCONNECTED);
 	} else {
 	} else {
 		blog(LOG_INFO, "Output '%s':  Reconnecting in %d seconds..",
 		blog(LOG_INFO, "Output '%s':  Reconnecting in %d seconds..",
@@ -1705,12 +1726,12 @@ void obs_output_signal_stop(obs_output_t *output, int code)
 
 
 	obs_output_end_data_capture(output);
 	obs_output_end_data_capture(output);
 
 
-	if ((output->reconnecting && code != OBS_OUTPUT_SUCCESS) ||
+	if ((reconnecting(output) && code != OBS_OUTPUT_SUCCESS) ||
 	    code == OBS_OUTPUT_DISCONNECTED) {
 	    code == OBS_OUTPUT_DISCONNECTED) {
 		output_reconnect(output);
 		output_reconnect(output);
 	} else {
 	} else {
-		if (output->delay_active) {
-			output->delay_active = false;
+		if (delay_active(output)) {
+			os_atomic_set_bool(&output->delay_active, false);
 			obs_output_end_data_capture(output);
 			obs_output_end_data_capture(output);
 		}
 		}
 		signal_stop(output, code);
 		signal_stop(output, code);