Browse Source

(API Change) Fix "apply service settings" functions

API changed from:
------------------------
EXPORT void obs_service_apply_encoder_settings(obs_service_t *service,
		obs_encoder_t *video_encoder,
		obs_encoder_t *audio_encoder);

void obs_service_info::apply_encoder_settings(void *data
			obs_encoder_t *video_encoder,
			obs_encoder_t *audio_encoder);

To:
------------------------
EXPORT void obs_service_apply_encoder_settings(obs_service_t *service,
		obs_data_t *video_encoder_settings,
		obs_data_t *audio_encoder_settings);

void obs_service_info::apply_encoder_settings(void *data
			obs_data_t *video_encoder_settings,
			obs_data_t *audio_encoder_settings);

These changes make it so that instead of an encoder potentially being
updated more than once with different settings, that these functions
will be called for the specific settings being used, and the settings
will be updated according to what's required by the service.

This fixes that design flaw and ensures that there's no case where
obs_encoder_update is called where the settings might not have
service-specific settings applied.
jp9000 10 years ago
parent
commit
b03eae57c6
5 changed files with 46 additions and 57 deletions
  1. 4 8
      libobs/obs-service.c
  2. 3 2
      libobs/obs-service.h
  3. 4 3
      libobs/obs.h
  4. 25 24
      obs/window-basic-main-outputs.cpp
  5. 10 20
      plugins/rtmp-services/rtmp-common.c

+ 4 - 8
libobs/obs-service.c

@@ -237,17 +237,13 @@ bool obs_service_initialize(struct obs_service *service,
 }
 }
 
 
 void obs_service_apply_encoder_settings(obs_service_t *service,
 void obs_service_apply_encoder_settings(obs_service_t *service,
-		obs_encoder_t *video_encoder, obs_encoder_t *audio_encoder)
+		obs_data_t *video_encoder_settings,
+		obs_data_t *audio_encoder_settings)
 {
 {
 	if (!service || !service->info.apply_encoder_settings)
 	if (!service || !service->info.apply_encoder_settings)
 		return;
 		return;
 
 
-	if (video_encoder && video_encoder->info.type != OBS_ENCODER_VIDEO)
-		video_encoder = NULL;
-	if (audio_encoder && audio_encoder->info.type != OBS_ENCODER_AUDIO)
-		audio_encoder = NULL;
-
-	if (video_encoder || audio_encoder)
+	if (video_encoder_settings || audio_encoder_settings)
 		service->info.apply_encoder_settings(service->context.data,
 		service->info.apply_encoder_settings(service->context.data,
-				video_encoder, audio_encoder);
+				video_encoder_settings, audio_encoder_settings);
 }
 }

+ 3 - 2
libobs/obs-service.h

@@ -65,8 +65,9 @@ struct obs_service_info {
 
 
 	bool (*supports_multitrack)(void *data);
 	bool (*supports_multitrack)(void *data);
 
 
-	void (*apply_encoder_settings)(void *data, obs_encoder_t *video_encoder,
-			obs_encoder_t *audio_encoder);
+	void (*apply_encoder_settings)(void *data,
+			obs_data_t *video_encoder_settings,
+			obs_data_t *audio_encoder_settings);
 
 
 	/* TODO: more stuff later */
 	/* TODO: more stuff later */
 };
 };

+ 4 - 3
libobs/obs.h

@@ -1341,11 +1341,12 @@ EXPORT const char *obs_service_get_password(const obs_service_t *service);
 /**
 /**
  * Applies service-specific video encoder settings.
  * Applies service-specific video encoder settings.
  *
  *
- * @param  video_encoder  Video encoder to apply settings to.  Optional.
- * @param  audio_encoder  Audio encoder to apply settings to.  Optional.
+ * @param  video_encoder_settings  Video encoder settings.  Optional.
+ * @param  audio_encoder_settings  Audio encoder settings.  Optional.
  */
  */
 EXPORT void obs_service_apply_encoder_settings(obs_service_t *service,
 EXPORT void obs_service_apply_encoder_settings(obs_service_t *service,
-		obs_encoder_t *video_encoder, obs_encoder_t *audio_encoder);
+		obs_data_t *video_encoder_settings,
+		obs_data_t *audio_encoder_settings);
 
 
 
 
 /* ------------------------------------------------------------------------- */
 /* ------------------------------------------------------------------------- */

+ 25 - 24
obs/window-basic-main-outputs.cpp

@@ -132,6 +132,9 @@ void SimpleOutput::Update()
 
 
 	obs_data_set_int(aacSettings, "bitrate", audioBitrate);
 	obs_data_set_int(aacSettings, "bitrate", audioBitrate);
 
 
+	obs_service_apply_encoder_settings(main->GetService(),
+			h264Settings, aacSettings);
+
 	obs_encoder_update(h264, h264Settings);
 	obs_encoder_update(h264, h264Settings);
 	obs_encoder_update(aac,  aacSettings);
 	obs_encoder_update(aac,  aacSettings);
 
 
@@ -144,8 +147,6 @@ inline void SimpleOutput::SetupOutputs()
 	SimpleOutput::Update();
 	SimpleOutput::Update();
 	obs_encoder_set_video(h264, obs_get_video());
 	obs_encoder_set_video(h264, obs_get_video());
 	obs_encoder_set_audio(aac,  obs_get_audio());
 	obs_encoder_set_audio(aac,  obs_get_audio());
-
-	obs_service_apply_encoder_settings(main->GetService(), h264, aac);
 }
 }
 
 
 bool SimpleOutput::StartStreaming(obs_service_t *service)
 bool SimpleOutput::StartStreaming(obs_service_t *service)
@@ -259,12 +260,12 @@ struct AdvancedOutput : BasicOutputHandler {
 
 
 	inline void UpdateStreamSettings();
 	inline void UpdateStreamSettings();
 	inline void UpdateRecordingSettings();
 	inline void UpdateRecordingSettings();
+	inline void UpdateAudioSettings();
 	virtual void Update() override;
 	virtual void Update() override;
 
 
 	inline void SetupStreaming();
 	inline void SetupStreaming();
 	inline void SetupRecording();
 	inline void SetupRecording();
 	inline void SetupFFmpeg();
 	inline void SetupFFmpeg();
-	inline void SetupAudio();
 	void SetupOutputs();
 	void SetupOutputs();
 
 
 	virtual bool StartStreaming(obs_service_t *service) override;
 	virtual bool StartStreaming(obs_service_t *service) override;
@@ -370,8 +371,16 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 
 
 void AdvancedOutput::UpdateStreamSettings()
 void AdvancedOutput::UpdateStreamSettings()
 {
 {
+	bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut",
+			"ApplyServiceSettings");
+
 	OBSData settings = GetDataFromJsonFile(
 	OBSData settings = GetDataFromJsonFile(
 			"obs-studio/basic/streamEncoder.json");
 			"obs-studio/basic/streamEncoder.json");
+
+	if (applyServiceSettings)
+		obs_service_apply_encoder_settings(main->GetService(),
+				settings, nullptr);
+
 	obs_encoder_update(h264Streaming, settings);
 	obs_encoder_update(h264Streaming, settings);
 }
 }
 
 
@@ -387,6 +396,7 @@ void AdvancedOutput::Update()
 	UpdateStreamSettings();
 	UpdateStreamSettings();
 	if (!useStreamEncoder && !ffmpegRecording)
 	if (!useStreamEncoder && !ffmpegRecording)
 		UpdateRecordingSettings();
 		UpdateRecordingSettings();
+	UpdateAudioSettings();
 }
 }
 
 
 inline void AdvancedOutput::SetupStreaming()
 inline void AdvancedOutput::SetupStreaming()
@@ -401,8 +411,6 @@ inline void AdvancedOutput::SetupStreaming()
 			"TrackIndex");
 			"TrackIndex");
 	int trackCount = config_get_int(main->Config(), "AdvOut",
 	int trackCount = config_get_int(main->Config(), "AdvOut",
 			"TrackCount");
 			"TrackCount");
-	bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut",
-			"ApplyServiceSettings");
 	unsigned int cx = 0;
 	unsigned int cx = 0;
 	unsigned int cy = 0;
 	unsigned int cy = 0;
 
 
@@ -416,33 +424,17 @@ inline void AdvancedOutput::SetupStreaming()
 
 
 	obs_output_set_video_encoder(streamOutput, h264Streaming);
 	obs_output_set_video_encoder(streamOutput, h264Streaming);
 
 
-	if (applyServiceSettings) {
-		obs_service_apply_encoder_settings(main->GetService(),
-				h264Streaming, nullptr);
-	}
-
 	if (multitrack) {
 	if (multitrack) {
 		int i = 0;
 		int i = 0;
-		for (; i < trackCount; i++) {
+		for (; i < trackCount; i++)
 			obs_output_set_audio_encoder(streamOutput, aacTrack[i],
 			obs_output_set_audio_encoder(streamOutput, aacTrack[i],
 					i);
 					i);
-
-			if (applyServiceSettings)
-				obs_service_apply_encoder_settings(
-						main->GetService(), nullptr,
-						aacTrack[i]);
-		}
-
 		for (; i < 4; i++)
 		for (; i < 4; i++)
 			obs_output_set_audio_encoder(streamOutput, nullptr, i);
 			obs_output_set_audio_encoder(streamOutput, nullptr, i);
 
 
 	} else {
 	} else {
 		obs_output_set_audio_encoder(streamOutput,
 		obs_output_set_audio_encoder(streamOutput,
 				aacTrack[trackIndex - 1], 0);
 				aacTrack[trackIndex - 1], 0);
-
-		if (applyServiceSettings)
-			obs_service_apply_encoder_settings(main->GetService(),
-					nullptr, aacTrack[trackIndex - 1]);
 	}
 	}
 }
 }
 
 
@@ -549,7 +541,7 @@ static inline void SetEncoderName(obs_encoder_t *encoder, const char *name,
 	obs_encoder_set_name(encoder, (name && *name) ? name : defaultName);
 	obs_encoder_set_name(encoder, (name && *name) ? name : defaultName);
 }
 }
 
 
-inline void AdvancedOutput::SetupAudio()
+inline void AdvancedOutput::UpdateAudioSettings()
 {
 {
 	int track1Bitrate = config_get_uint(main->Config(), "AdvOut",
 	int track1Bitrate = config_get_uint(main->Config(), "AdvOut",
 			"Track1Bitrate");
 			"Track1Bitrate");
@@ -567,6 +559,8 @@ inline void AdvancedOutput::SetupAudio()
 			"Track3Name");
 			"Track3Name");
 	const char *name4 = config_get_string(main->Config(), "AdvOut",
 	const char *name4 = config_get_string(main->Config(), "AdvOut",
 			"Track4Name");
 			"Track4Name");
+	bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut",
+			"ApplyServiceSettings");
 	obs_data_t *settings[4];
 	obs_data_t *settings[4];
 
 
 	for (size_t i = 0; i < 4; i++)
 	for (size_t i = 0; i < 4; i++)
@@ -583,6 +577,10 @@ inline void AdvancedOutput::SetupAudio()
 	SetEncoderName(aacTrack[3], name4, "Track4");
 	SetEncoderName(aacTrack[3], name4, "Track4");
 
 
 	for (size_t i = 0; i < 4; i++) {
 	for (size_t i = 0; i < 4; i++) {
+		if (applyServiceSettings)
+			obs_service_apply_encoder_settings(main->GetService(),
+					nullptr, settings[i]);
+
 		obs_encoder_update(aacTrack[i], settings[i]);
 		obs_encoder_update(aacTrack[i], settings[i]);
 		obs_data_release(settings[i]);
 		obs_data_release(settings[i]);
 	}
 	}
@@ -599,7 +597,6 @@ void AdvancedOutput::SetupOutputs()
 	obs_encoder_set_audio(aacTrack[3], obs_get_audio());
 	obs_encoder_set_audio(aacTrack[3], obs_get_audio());
 
 
 	SetupStreaming();
 	SetupStreaming();
-	SetupAudio();
 
 
 	if (ffmpegRecording)
 	if (ffmpegRecording)
 		SetupFFmpeg();
 		SetupFFmpeg();
@@ -614,6 +611,8 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
 		UpdateStreamSettings();
 		UpdateStreamSettings();
 	}
 	}
 
 
+	UpdateAudioSettings();
+
 	if (!Active())
 	if (!Active())
 		SetupOutputs();
 		SetupOutputs();
 
 
@@ -646,6 +645,8 @@ bool AdvancedOutput::StartRecording()
 		UpdateStreamSettings();
 		UpdateStreamSettings();
 	}
 	}
 
 
+	UpdateAudioSettings();
+
 	if (!Active())
 	if (!Active())
 		SetupOutputs();
 		SetupOutputs();
 
 

+ 10 - 20
plugins/rtmp-services/rtmp-common.c

@@ -225,11 +225,9 @@ static obs_properties_t *rtmp_common_properties(void *unused)
 	return ppts;
 	return ppts;
 }
 }
 
 
-static void apply_video_encoder_settings(obs_encoder_t *encoder,
+static void apply_video_encoder_settings(obs_data_t *settings,
 		json_t *recommended)
 		json_t *recommended)
 {
 {
-	obs_data_t *settings = obs_encoder_get_settings(encoder);
-
 	json_t *item = json_object_get(recommended, "keyint");
 	json_t *item = json_object_get(recommended, "keyint");
 	if (item && json_is_integer(item)) {
 	if (item && json_is_integer(item)) {
 		int keyint = (int)json_integer_value(item);
 		int keyint = (int)json_integer_value(item);
@@ -256,29 +254,21 @@ static void apply_video_encoder_settings(obs_encoder_t *encoder,
 			obs_data_set_int(settings, "buffer_size", max_bitrate);
 			obs_data_set_int(settings, "buffer_size", max_bitrate);
 		}
 		}
 	}
 	}
-
-	obs_encoder_update(encoder, settings);
-	obs_data_release(settings);
 }
 }
 
 
-static void apply_audio_encoder_settings(obs_encoder_t *encoder,
+static void apply_audio_encoder_settings(obs_data_t *settings,
 		json_t *recommended)
 		json_t *recommended)
 {
 {
-	obs_data_t *settings = obs_encoder_get_settings(encoder);
-
 	json_t *item = json_object_get(recommended, "max audio bitrate");
 	json_t *item = json_object_get(recommended, "max audio bitrate");
 	if (item && json_is_integer(item)) {
 	if (item && json_is_integer(item)) {
 		int max_bitrate = (int)json_integer_value(item);
 		int max_bitrate = (int)json_integer_value(item);
 		if (obs_data_get_int(settings, "bitrate") > max_bitrate)
 		if (obs_data_get_int(settings, "bitrate") > max_bitrate)
 			obs_data_set_int(settings, "bitrate", max_bitrate);
 			obs_data_set_int(settings, "bitrate", max_bitrate);
 	}
 	}
-
-	obs_encoder_update(encoder, settings);
-	obs_data_release(settings);
 }
 }
 
 
 static void initialize_output(struct rtmp_common *service, json_t *root,
 static void initialize_output(struct rtmp_common *service, json_t *root,
-		obs_encoder_t *video_encoder, obs_encoder_t *audio_encoder)
+		obs_data_t *video_settings, obs_data_t *audio_settings)
 {
 {
 	json_t        *json_service = find_service(root, service->service);
 	json_t        *json_service = find_service(root, service->service);
 	json_t        *recommended;
 	json_t        *recommended;
@@ -294,14 +284,14 @@ static void initialize_output(struct rtmp_common *service, json_t *root,
 	if (!recommended)
 	if (!recommended)
 		return;
 		return;
 
 
-	if (video_encoder)
-		apply_video_encoder_settings(video_encoder, recommended);
-	if (audio_encoder)
-		apply_audio_encoder_settings(audio_encoder, recommended);
+	if (video_settings)
+		apply_video_encoder_settings(video_settings, recommended);
+	if (audio_settings)
+		apply_audio_encoder_settings(audio_settings, recommended);
 }
 }
 
 
 static void rtmp_common_apply_settings(void *data,
 static void rtmp_common_apply_settings(void *data,
-		obs_encoder_t *video_encoder, obs_encoder_t *audio_encoder)
+		obs_data_t *video_settings, obs_data_t *audio_settings)
 {
 {
 	struct rtmp_common *service = data;
 	struct rtmp_common *service = data;
 	char               *file;
 	char               *file;
@@ -310,8 +300,8 @@ static void rtmp_common_apply_settings(void *data,
 	if (file) {
 	if (file) {
 		json_t *root = open_json_file(file);
 		json_t *root = open_json_file(file);
 		if (root) {
 		if (root) {
-			initialize_output(service, root, video_encoder,
-					audio_encoder);
+			initialize_output(service, root, video_settings,
+					audio_settings);
 			json_decref(root);
 			json_decref(root);
 		}
 		}
 		bfree(file);
 		bfree(file);