|
@@ -2515,330 +2515,6 @@ static inline bool arg_is(const char *arg, const char *long_form,
|
|
|
(short_form && strcmp(arg, short_form) == 0);
|
|
|
}
|
|
|
|
|
|
-static bool update_ffmpeg_output(ConfigFile &config)
|
|
|
-{
|
|
|
- if (config_has_user_value(config, "AdvOut", "FFOutputToFile"))
|
|
|
- return false;
|
|
|
-
|
|
|
- const char *url = config_get_string(config, "AdvOut", "FFURL");
|
|
|
- if (!url)
|
|
|
- return false;
|
|
|
-
|
|
|
- bool isActualURL = strstr(url, "://") != nullptr;
|
|
|
- if (isActualURL)
|
|
|
- return false;
|
|
|
-
|
|
|
- string urlStr = url;
|
|
|
- string extension;
|
|
|
-
|
|
|
- for (size_t i = urlStr.length(); i > 0; i--) {
|
|
|
- size_t idx = i - 1;
|
|
|
-
|
|
|
- if (urlStr[idx] == '.') {
|
|
|
- extension = &urlStr[i];
|
|
|
- }
|
|
|
-
|
|
|
- if (urlStr[idx] == '\\' || urlStr[idx] == '/') {
|
|
|
- urlStr[idx] = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (urlStr.empty() || extension.empty())
|
|
|
- return false;
|
|
|
-
|
|
|
- config_remove_value(config, "AdvOut", "FFURL");
|
|
|
- config_set_string(config, "AdvOut", "FFFilePath", urlStr.c_str());
|
|
|
- config_set_string(config, "AdvOut", "FFExtension", extension.c_str());
|
|
|
- config_set_bool(config, "AdvOut", "FFOutputToFile", true);
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-static bool move_reconnect_settings(ConfigFile &config, const char *sec)
|
|
|
-{
|
|
|
- bool changed = false;
|
|
|
-
|
|
|
- if (config_has_user_value(config, sec, "Reconnect")) {
|
|
|
- bool reconnect = config_get_bool(config, sec, "Reconnect");
|
|
|
- config_set_bool(config, "Output", "Reconnect", reconnect);
|
|
|
- changed = true;
|
|
|
- }
|
|
|
- if (config_has_user_value(config, sec, "RetryDelay")) {
|
|
|
- int delay = (int)config_get_uint(config, sec, "RetryDelay");
|
|
|
- config_set_uint(config, "Output", "RetryDelay", delay);
|
|
|
- changed = true;
|
|
|
- }
|
|
|
- if (config_has_user_value(config, sec, "MaxRetries")) {
|
|
|
- int retries = (int)config_get_uint(config, sec, "MaxRetries");
|
|
|
- config_set_uint(config, "Output", "MaxRetries", retries);
|
|
|
- changed = true;
|
|
|
- }
|
|
|
-
|
|
|
- return changed;
|
|
|
-}
|
|
|
-
|
|
|
-static bool update_reconnect(ConfigFile &config)
|
|
|
-{
|
|
|
- if (!config_has_user_value(config, "Output", "Mode"))
|
|
|
- return false;
|
|
|
-
|
|
|
- const char *mode = config_get_string(config, "Output", "Mode");
|
|
|
- if (!mode)
|
|
|
- return false;
|
|
|
-
|
|
|
- const char *section = (strcmp(mode, "Advanced") == 0) ? "AdvOut"
|
|
|
- : "SimpleOutput";
|
|
|
-
|
|
|
- if (move_reconnect_settings(config, section)) {
|
|
|
- config_remove_value(config, "SimpleOutput", "Reconnect");
|
|
|
- config_remove_value(config, "SimpleOutput", "RetryDelay");
|
|
|
- config_remove_value(config, "SimpleOutput", "MaxRetries");
|
|
|
- config_remove_value(config, "AdvOut", "Reconnect");
|
|
|
- config_remove_value(config, "AdvOut", "RetryDelay");
|
|
|
- config_remove_value(config, "AdvOut", "MaxRetries");
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
-}
|
|
|
-
|
|
|
-static void convert_nvenc_h264_presets(obs_data_t *data)
|
|
|
-{
|
|
|
- const char *preset = obs_data_get_string(data, "preset");
|
|
|
- const char *rc = obs_data_get_string(data, "rate_control");
|
|
|
-
|
|
|
- // If already using SDK10+ preset, return early.
|
|
|
- if (astrcmpi_n(preset, "p", 1) == 0) {
|
|
|
- obs_data_set_string(data, "preset2", preset);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (astrcmpi(rc, "lossless") == 0 && astrcmpi(preset, "mq")) {
|
|
|
- obs_data_set_string(data, "preset2", "p3");
|
|
|
- obs_data_set_string(data, "tune", "lossless");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(rc, "lossless") == 0 && astrcmpi(preset, "hp")) {
|
|
|
- obs_data_set_string(data, "preset2", "p2");
|
|
|
- obs_data_set_string(data, "tune", "lossless");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "mq") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p5");
|
|
|
- obs_data_set_string(data, "tune", "hq");
|
|
|
- obs_data_set_string(data, "multipass", "qres");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "hq") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p5");
|
|
|
- obs_data_set_string(data, "tune", "hq");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "default") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p3");
|
|
|
- obs_data_set_string(data, "tune", "hq");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "hp") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p1");
|
|
|
- obs_data_set_string(data, "tune", "hq");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "ll") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p3");
|
|
|
- obs_data_set_string(data, "tune", "ll");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "llhq") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p4");
|
|
|
- obs_data_set_string(data, "tune", "ll");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "llhp") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p2");
|
|
|
- obs_data_set_string(data, "tune", "ll");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static void convert_nvenc_hevc_presets(obs_data_t *data)
|
|
|
-{
|
|
|
- const char *preset = obs_data_get_string(data, "preset");
|
|
|
- const char *rc = obs_data_get_string(data, "rate_control");
|
|
|
-
|
|
|
- // If already using SDK10+ preset, return early.
|
|
|
- if (astrcmpi_n(preset, "p", 1) == 0) {
|
|
|
- obs_data_set_string(data, "preset2", preset);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (astrcmpi(rc, "lossless") == 0 && astrcmpi(preset, "mq")) {
|
|
|
- obs_data_set_string(data, "preset2", "p5");
|
|
|
- obs_data_set_string(data, "tune", "lossless");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(rc, "lossless") == 0 && astrcmpi(preset, "hp")) {
|
|
|
- obs_data_set_string(data, "preset2", "p3");
|
|
|
- obs_data_set_string(data, "tune", "lossless");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "mq") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p6");
|
|
|
- obs_data_set_string(data, "tune", "hq");
|
|
|
- obs_data_set_string(data, "multipass", "qres");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "hq") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p6");
|
|
|
- obs_data_set_string(data, "tune", "hq");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "default") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p5");
|
|
|
- obs_data_set_string(data, "tune", "hq");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "hp") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p1");
|
|
|
- obs_data_set_string(data, "tune", "hq");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "ll") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p3");
|
|
|
- obs_data_set_string(data, "tune", "ll");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "llhq") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p4");
|
|
|
- obs_data_set_string(data, "tune", "ll");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
-
|
|
|
- } else if (astrcmpi(preset, "llhp") == 0) {
|
|
|
- obs_data_set_string(data, "preset2", "p2");
|
|
|
- obs_data_set_string(data, "tune", "ll");
|
|
|
- obs_data_set_string(data, "multipass", "disabled");
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static void convert_28_1_encoder_setting(const char *encoder, const char *file)
|
|
|
-{
|
|
|
- OBSDataAutoRelease data =
|
|
|
- obs_data_create_from_json_file_safe(file, "bak");
|
|
|
- bool modified = false;
|
|
|
-
|
|
|
- if (astrcmpi(encoder, "jim_nvenc") == 0 ||
|
|
|
- astrcmpi(encoder, "ffmpeg_nvenc") == 0) {
|
|
|
-
|
|
|
- if (obs_data_has_user_value(data, "preset") &&
|
|
|
- !obs_data_has_user_value(data, "preset2")) {
|
|
|
- convert_nvenc_h264_presets(data);
|
|
|
-
|
|
|
- modified = true;
|
|
|
- }
|
|
|
- } else if (astrcmpi(encoder, "jim_hevc_nvenc") == 0 ||
|
|
|
- astrcmpi(encoder, "ffmpeg_hevc_nvenc") == 0) {
|
|
|
-
|
|
|
- if (obs_data_has_user_value(data, "preset") &&
|
|
|
- !obs_data_has_user_value(data, "preset2")) {
|
|
|
- convert_nvenc_hevc_presets(data);
|
|
|
-
|
|
|
- modified = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (modified)
|
|
|
- obs_data_save_json_safe(data, file, "tmp", "bak");
|
|
|
-}
|
|
|
-
|
|
|
-bool update_nvenc_presets(ConfigFile &config)
|
|
|
-{
|
|
|
- if (config_has_user_value(config, "SimpleOutput", "NVENCPreset2") ||
|
|
|
- !config_has_user_value(config, "SimpleOutput", "NVENCPreset"))
|
|
|
- return false;
|
|
|
-
|
|
|
- const char *streamEncoder =
|
|
|
- config_get_string(config, "SimpleOutput", "StreamEncoder");
|
|
|
- const char *nvencPreset =
|
|
|
- config_get_string(config, "SimpleOutput", "NVENCPreset");
|
|
|
-
|
|
|
- OBSDataAutoRelease data = obs_data_create();
|
|
|
- obs_data_set_string(data, "preset", nvencPreset);
|
|
|
-
|
|
|
- if (astrcmpi(streamEncoder, "nvenc_hevc") == 0) {
|
|
|
- convert_nvenc_hevc_presets(data);
|
|
|
- } else {
|
|
|
- convert_nvenc_h264_presets(data);
|
|
|
- }
|
|
|
-
|
|
|
- config_set_string(config, "SimpleOutput", "NVENCPreset2",
|
|
|
- obs_data_get_string(data, "preset2"));
|
|
|
-
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-static void upgrade_settings(void)
|
|
|
-{
|
|
|
- char path[512];
|
|
|
- int pathlen = GetConfigPath(path, 512, "obs-studio/basic/profiles");
|
|
|
-
|
|
|
- if (pathlen <= 0)
|
|
|
- return;
|
|
|
- if (!os_file_exists(path))
|
|
|
- return;
|
|
|
-
|
|
|
- os_dir_t *dir = os_opendir(path);
|
|
|
- if (!dir)
|
|
|
- return;
|
|
|
-
|
|
|
- struct os_dirent *ent = os_readdir(dir);
|
|
|
-
|
|
|
- while (ent) {
|
|
|
- if (ent->directory && strcmp(ent->d_name, ".") != 0 &&
|
|
|
- strcmp(ent->d_name, "..") != 0) {
|
|
|
- strcat(path, "/");
|
|
|
- strcat(path, ent->d_name);
|
|
|
- strcat(path, "/basic.ini");
|
|
|
-
|
|
|
- ConfigFile config;
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = config.Open(path, CONFIG_OPEN_EXISTING);
|
|
|
- if (ret == CONFIG_SUCCESS) {
|
|
|
- if (update_ffmpeg_output(config) ||
|
|
|
- update_reconnect(config)) {
|
|
|
- config_save_safe(config, "tmp",
|
|
|
- nullptr);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (config) {
|
|
|
- const char *sEnc = config_get_string(
|
|
|
- config, "AdvOut", "Encoder");
|
|
|
- const char *rEnc = config_get_string(
|
|
|
- config, "AdvOut", "RecEncoder");
|
|
|
-
|
|
|
- /* replace "cbr" option with "rate_control" for
|
|
|
- * each profile's encoder data */
|
|
|
- path[pathlen] = 0;
|
|
|
- strcat(path, "/");
|
|
|
- strcat(path, ent->d_name);
|
|
|
- strcat(path, "/recordEncoder.json");
|
|
|
- convert_28_1_encoder_setting(rEnc, path);
|
|
|
-
|
|
|
- path[pathlen] = 0;
|
|
|
- strcat(path, "/");
|
|
|
- strcat(path, ent->d_name);
|
|
|
- strcat(path, "/streamEncoder.json");
|
|
|
- convert_28_1_encoder_setting(sEnc, path);
|
|
|
- }
|
|
|
-
|
|
|
- path[pathlen] = 0;
|
|
|
- }
|
|
|
-
|
|
|
- ent = os_readdir(dir);
|
|
|
- }
|
|
|
-
|
|
|
- os_closedir(dir);
|
|
|
-}
|
|
|
-
|
|
|
static void check_safe_mode_sentinel(void)
|
|
|
{
|
|
|
#ifndef NDEBUG
|
|
@@ -3122,7 +2798,6 @@ int main(int argc, char *argv[])
|
|
|
#endif
|
|
|
|
|
|
check_safe_mode_sentinel();
|
|
|
- upgrade_settings();
|
|
|
|
|
|
fstream logFile;
|
|
|
|