Browse Source

rtmp-services: Extract Twitch specific info from ingest update code

Ruwen Hahn 1 year ago
parent
commit
717161f246
1 changed files with 100 additions and 60 deletions
  1. 100 60
      plugins/rtmp-services/service-specific/twitch.c

+ 100 - 60
plugins/rtmp-services/service-specific/twitch.c

@@ -7,31 +7,45 @@
 
 #include "twitch.h"
 
-static update_info_t *twitch_update_info = NULL;
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static bool ingests_refreshed = false;
-static bool ingests_refreshing = false;
-static bool ingests_loaded = false;
-
 struct ingest {
 	char *name;
 	char *url;
 };
 
-static DARRAY(struct ingest) cur_ingests;
+struct service_ingests {
+	update_info_t *update_info;
+	pthread_mutex_t mutex;
+	bool ingests_refreshed;
+	bool ingests_refreshing;
+	bool ingests_loaded;
+	DARRAY(struct ingest) cur_ingests;
+	const char *cache_old_filename;
+	const char *cache_new_filename;
+};
 
-static void free_ingests(void)
+static struct service_ingests twitch = {
+	.update_info = NULL,
+	.mutex = PTHREAD_MUTEX_INITIALIZER,
+	.ingests_refreshed = false,
+	.ingests_refreshing = false,
+	.ingests_loaded = false,
+	.cur_ingests = {0},
+	.cache_old_filename = "twitch_ingests.json",
+	.cache_new_filename = "twitch_ingests.new.json"};
+
+static void free_ingests(struct service_ingests *si)
 {
-	for (size_t i = 0; i < cur_ingests.num; i++) {
-		struct ingest *ingest = cur_ingests.array + i;
+	for (size_t i = 0; i < si->cur_ingests.num; i++) {
+		struct ingest *ingest = si->cur_ingests.array + i;
 		bfree(ingest->name);
 		bfree(ingest->url);
 	}
 
-	da_free(cur_ingests);
+	da_free(si->cur_ingests);
 }
 
-static bool load_ingests(const char *json, bool write_file)
+static bool load_ingests(struct service_ingests *si, const char *json,
+			 bool write_file)
 {
 	json_t *root;
 	json_t *ingests;
@@ -49,10 +63,10 @@ static bool load_ingests(const char *json, bool write_file)
 		goto finish;
 
 	count = json_array_size(ingests);
-	if (count <= 1 && cur_ingests.num)
+	if (count <= 1 && si->cur_ingests.num)
 		goto finish;
 
-	free_ingests();
+	free_ingests(si);
 
 	for (size_t i = 0; i < count; i++) {
 		json_t *item = json_array_get(ingests, i);
@@ -79,10 +93,10 @@ static bool load_ingests(const char *json, bool write_file)
 		ingest.name = bstrdup(name_str);
 		ingest.url = url.array;
 
-		da_push_back(cur_ingests, &ingest);
+		da_push_back(si->cur_ingests, &ingest);
 	}
 
-	if (!cur_ingests.num)
+	if (!si->cur_ingests.num)
 		goto finish;
 
 	success = true;
@@ -90,8 +104,8 @@ static bool load_ingests(const char *json, bool write_file)
 	if (!write_file)
 		goto finish;
 
-	cache_old = obs_module_config_path("twitch_ingests.json");
-	cache_new = obs_module_config_path("twitch_ingests.new.json");
+	cache_old = obs_module_config_path(si->cache_old_filename);
+	cache_new = obs_module_config_path(si->cache_new_filename);
 
 	os_quick_write_utf8_file(cache_new, json, strlen(json), false);
 	os_safe_replace(cache_old, cache_new, NULL);
@@ -105,78 +119,88 @@ finish:
 	return success;
 }
 
-static bool twitch_ingest_update(void *param, struct file_download_data *data)
+static bool ingest_update(void *param, struct file_download_data *data)
 {
+	struct service_ingests *service = param;
 	bool success;
 
-	pthread_mutex_lock(&mutex);
-	success = load_ingests((const char *)data->buffer.array, true);
-	pthread_mutex_unlock(&mutex);
+	pthread_mutex_lock(&service->mutex);
+	success = load_ingests(service, (const char *)data->buffer.array, true);
+	pthread_mutex_unlock(&service->mutex);
 
 	if (success) {
-		os_atomic_set_bool(&ingests_refreshed, true);
-		os_atomic_set_bool(&ingests_loaded, true);
+		os_atomic_set_bool(&service->ingests_refreshed, true);
+		os_atomic_set_bool(&service->ingests_loaded, true);
 	}
 
-	UNUSED_PARAMETER(param);
 	return true;
 }
 
 void twitch_ingests_lock(void)
 {
-	pthread_mutex_lock(&mutex);
+	pthread_mutex_lock(&twitch.mutex);
 }
 
 void twitch_ingests_unlock(void)
 {
-	pthread_mutex_unlock(&mutex);
+	pthread_mutex_unlock(&twitch.mutex);
 }
 
 size_t twitch_ingest_count(void)
 {
-	return cur_ingests.num;
+	return twitch.cur_ingests.num;
 }
 
-struct twitch_ingest twitch_ingest(size_t idx)
+struct twitch_ingest get_ingest(struct service_ingests *si, size_t idx)
 {
 	struct twitch_ingest ingest;
 
-	if (cur_ingests.num <= idx) {
+	if (si->cur_ingests.num <= idx) {
 		ingest.name = NULL;
 		ingest.url = NULL;
 	} else {
-		ingest = *(struct twitch_ingest *)(cur_ingests.array + idx);
+		ingest = *(struct twitch_ingest *)(si->cur_ingests.array + idx);
 	}
 
 	return ingest;
 }
 
+struct twitch_ingest twitch_ingest(size_t idx)
+{
+	return get_ingest(&twitch, idx);
+}
+
+void init_service_data(struct service_ingests *si)
+{
+	da_init(si->cur_ingests);
+	pthread_mutex_init(&si->mutex, NULL);
+}
+
 void init_twitch_data(void)
 {
-	da_init(cur_ingests);
-	pthread_mutex_init(&mutex, NULL);
+	init_service_data(&twitch);
 }
 
 extern const char *get_module_name(void);
 
-void twitch_ingests_refresh(int seconds)
+void service_ingests_refresh(struct service_ingests *si, int seconds,
+			     const char *log_prefix, const char *file_url)
 {
-	if (os_atomic_load_bool(&ingests_refreshed))
+	if (os_atomic_load_bool(&si->ingests_refreshed))
 		return;
 
-	if (!os_atomic_load_bool(&ingests_refreshing)) {
-		os_atomic_set_bool(&ingests_refreshing, true);
+	if (!os_atomic_load_bool(&si->ingests_refreshing)) {
+		os_atomic_set_bool(&si->ingests_refreshing, true);
 
-		twitch_update_info = update_info_create_single(
-			"[twitch ingest update] ", get_module_name(),
-			"https://ingest.twitch.tv/ingests",
-			twitch_ingest_update, NULL);
+		si->update_info =
+			update_info_create_single(log_prefix, get_module_name(),
+						  file_url, ingest_update, si);
 	}
 
 	/* wait five seconds max when loading ingests for the first time */
-	if (!os_atomic_load_bool(&ingests_loaded)) {
+	if (!os_atomic_load_bool(&si->ingests_loaded)) {
 		for (int i = 0; i < seconds * 100; i++) {
-			if (os_atomic_load_bool(&ingests_refreshed)) {
+			if (os_atomic_load_bool(&si->ingests_refreshed)) {
 				break;
 			}
 			os_sleep_ms(10);
@@ -184,38 +208,54 @@ void twitch_ingests_refresh(int seconds)
 	}
 }
 
-void load_twitch_data(void)
+void twitch_ingests_refresh(int seconds)
 {
-	char *twitch_cache = obs_module_config_path("twitch_ingests.json");
+	service_ingests_refresh(&twitch, seconds, "[twitch ingest update] ",
+				"https://ingest.twitch.tv/ingests");
+}
 
-	struct ingest def = {.name = bstrdup("Default"),
-			     .url = bstrdup("rtmp://live.twitch.tv/app")};
+void load_service_data(struct service_ingests *si, const char *cache_filename,
+		       struct ingest *def)
+{
+	char *service_cache = obs_module_config_path(cache_filename);
 
-	pthread_mutex_lock(&mutex);
-	da_push_back(cur_ingests, &def);
-	pthread_mutex_unlock(&mutex);
+	pthread_mutex_lock(&si->mutex);
+	da_push_back(si->cur_ingests, def);
+	pthread_mutex_unlock(&si->mutex);
 
-	if (os_file_exists(twitch_cache)) {
-		char *data = os_quick_read_utf8_file(twitch_cache);
+	if (os_file_exists(service_cache)) {
+		char *data = os_quick_read_utf8_file(service_cache);
 		bool success;
 
-		pthread_mutex_lock(&mutex);
-		success = load_ingests(data, false);
-		pthread_mutex_unlock(&mutex);
+		pthread_mutex_lock(&si->mutex);
+		success = load_ingests(si, data, false);
+		pthread_mutex_unlock(&si->mutex);
 
 		if (success) {
-			os_atomic_set_bool(&ingests_loaded, true);
+			os_atomic_set_bool(&si->ingests_loaded, true);
 		}
 
 		bfree(data);
 	}
 
-	bfree(twitch_cache);
+	bfree(service_cache);
+}
+
+void load_twitch_data(void)
+{
+	struct ingest def = {.name = bstrdup("Default"),
+			     .url = bstrdup("rtmp://live.twitch.tv/app")};
+	load_service_data(&twitch, "twitch_ingests.json", &def);
+}
+
+void unload_service_data(struct service_ingests *si)
+{
+	update_info_destroy(si->update_info);
+	free_ingests(si);
+	pthread_mutex_destroy(&si->mutex);
 }
 
 void unload_twitch_data(void)
 {
-	update_info_destroy(twitch_update_info);
-	free_ingests();
-	pthread_mutex_destroy(&mutex);
+	unload_service_data(&twitch);
 }