From b03eae57c68a458842dd45c27e17e85c413bff62 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Sat, 7 Mar 2015 16:32:00 -0800 Subject: [PATCH] (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. --- libobs/obs-service.c | 12 +++---- libobs/obs-service.h | 5 +-- libobs/obs.h | 7 +++-- obs/window-basic-main-outputs.cpp | 49 +++++++++++++++-------------- plugins/rtmp-services/rtmp-common.c | 30 ++++++------------ 5 files changed, 46 insertions(+), 57 deletions(-) diff --git a/libobs/obs-service.c b/libobs/obs-service.c index e27bef6c5..222513423 100644 --- a/libobs/obs-service.c +++ b/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, - 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) 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, - video_encoder, audio_encoder); + video_encoder_settings, audio_encoder_settings); } diff --git a/libobs/obs-service.h b/libobs/obs-service.h index e220cdc4a..c5b464ae3 100644 --- a/libobs/obs-service.h +++ b/libobs/obs-service.h @@ -65,8 +65,9 @@ struct obs_service_info { 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 */ }; diff --git a/libobs/obs.h b/libobs/obs.h index 4a39befaf..e6208a492 100644 --- a/libobs/obs.h +++ b/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. * - * @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, - obs_encoder_t *video_encoder, obs_encoder_t *audio_encoder); + obs_data_t *video_encoder_settings, + obs_data_t *audio_encoder_settings); /* ------------------------------------------------------------------------- */ diff --git a/obs/window-basic-main-outputs.cpp b/obs/window-basic-main-outputs.cpp index 1511f0c57..e6957877b 100644 --- a/obs/window-basic-main-outputs.cpp +++ b/obs/window-basic-main-outputs.cpp @@ -132,6 +132,9 @@ void SimpleOutput::Update() obs_data_set_int(aacSettings, "bitrate", audioBitrate); + obs_service_apply_encoder_settings(main->GetService(), + h264Settings, aacSettings); + obs_encoder_update(h264, h264Settings); obs_encoder_update(aac, aacSettings); @@ -144,8 +147,6 @@ inline void SimpleOutput::SetupOutputs() SimpleOutput::Update(); obs_encoder_set_video(h264, obs_get_video()); obs_encoder_set_audio(aac, obs_get_audio()); - - obs_service_apply_encoder_settings(main->GetService(), h264, aac); } bool SimpleOutput::StartStreaming(obs_service_t *service) @@ -259,12 +260,12 @@ struct AdvancedOutput : BasicOutputHandler { inline void UpdateStreamSettings(); inline void UpdateRecordingSettings(); + inline void UpdateAudioSettings(); virtual void Update() override; inline void SetupStreaming(); inline void SetupRecording(); inline void SetupFFmpeg(); - inline void SetupAudio(); void SetupOutputs(); virtual bool StartStreaming(obs_service_t *service) override; @@ -370,8 +371,16 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_) void AdvancedOutput::UpdateStreamSettings() { + bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut", + "ApplyServiceSettings"); + OBSData settings = GetDataFromJsonFile( "obs-studio/basic/streamEncoder.json"); + + if (applyServiceSettings) + obs_service_apply_encoder_settings(main->GetService(), + settings, nullptr); + obs_encoder_update(h264Streaming, settings); } @@ -387,6 +396,7 @@ void AdvancedOutput::Update() UpdateStreamSettings(); if (!useStreamEncoder && !ffmpegRecording) UpdateRecordingSettings(); + UpdateAudioSettings(); } inline void AdvancedOutput::SetupStreaming() @@ -401,8 +411,6 @@ inline void AdvancedOutput::SetupStreaming() "TrackIndex"); int trackCount = config_get_int(main->Config(), "AdvOut", "TrackCount"); - bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut", - "ApplyServiceSettings"); unsigned int cx = 0; unsigned int cy = 0; @@ -416,33 +424,17 @@ inline void AdvancedOutput::SetupStreaming() obs_output_set_video_encoder(streamOutput, h264Streaming); - if (applyServiceSettings) { - obs_service_apply_encoder_settings(main->GetService(), - h264Streaming, nullptr); - } - if (multitrack) { int i = 0; - for (; i < trackCount; i++) { + for (; i < trackCount; i++) obs_output_set_audio_encoder(streamOutput, aacTrack[i], i); - - if (applyServiceSettings) - obs_service_apply_encoder_settings( - main->GetService(), nullptr, - aacTrack[i]); - } - for (; i < 4; i++) obs_output_set_audio_encoder(streamOutput, nullptr, i); } else { obs_output_set_audio_encoder(streamOutput, 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); } -inline void AdvancedOutput::SetupAudio() +inline void AdvancedOutput::UpdateAudioSettings() { int track1Bitrate = config_get_uint(main->Config(), "AdvOut", "Track1Bitrate"); @@ -567,6 +559,8 @@ inline void AdvancedOutput::SetupAudio() "Track3Name"); const char *name4 = config_get_string(main->Config(), "AdvOut", "Track4Name"); + bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut", + "ApplyServiceSettings"); obs_data_t *settings[4]; for (size_t i = 0; i < 4; i++) @@ -583,6 +577,10 @@ inline void AdvancedOutput::SetupAudio() SetEncoderName(aacTrack[3], name4, "Track4"); 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_data_release(settings[i]); } @@ -599,7 +597,6 @@ void AdvancedOutput::SetupOutputs() obs_encoder_set_audio(aacTrack[3], obs_get_audio()); SetupStreaming(); - SetupAudio(); if (ffmpegRecording) SetupFFmpeg(); @@ -614,6 +611,8 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) UpdateStreamSettings(); } + UpdateAudioSettings(); + if (!Active()) SetupOutputs(); @@ -646,6 +645,8 @@ bool AdvancedOutput::StartRecording() UpdateStreamSettings(); } + UpdateAudioSettings(); + if (!Active()) SetupOutputs(); diff --git a/plugins/rtmp-services/rtmp-common.c b/plugins/rtmp-services/rtmp-common.c index ec5898245..f62984307 100644 --- a/plugins/rtmp-services/rtmp-common.c +++ b/plugins/rtmp-services/rtmp-common.c @@ -225,11 +225,9 @@ static obs_properties_t *rtmp_common_properties(void *unused) 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) { - obs_data_t *settings = obs_encoder_get_settings(encoder); - json_t *item = json_object_get(recommended, "keyint"); if (item && json_is_integer(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_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) { - obs_data_t *settings = obs_encoder_get_settings(encoder); - json_t *item = json_object_get(recommended, "max audio bitrate"); if (item && json_is_integer(item)) { int max_bitrate = (int)json_integer_value(item); if (obs_data_get_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, - 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 *recommended; @@ -294,14 +284,14 @@ static void initialize_output(struct rtmp_common *service, json_t *root, if (!recommended) 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, - 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; char *file; @@ -310,8 +300,8 @@ static void rtmp_common_apply_settings(void *data, if (file) { json_t *root = open_json_file(file); if (root) { - initialize_output(service, root, video_encoder, - audio_encoder); + initialize_output(service, root, video_settings, + audio_settings); json_decref(root); } bfree(file);