/** * @file src/config.cpp * @brief todo */ #include #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "file_handler.h" #include "logging.h" #include "utility.h" #include "platform/common.h" #ifdef _WIN32 #include #endif #ifndef __APPLE__ // For NVENC legacy constants #include #endif namespace fs = std::filesystem; using namespace std::literals; #define CA_DIR "credentials" #define PRIVATE_KEY_FILE CA_DIR "/cakey.pem" #define CERTIFICATE_FILE CA_DIR "/cacert.pem" #define APPS_JSON_PATH platf::appdata().string() + "/apps.json" namespace config { namespace nv { nvenc::nvenc_two_pass twopass_from_view(const std::string_view &preset) { if (preset == "disabled") return nvenc::nvenc_two_pass::disabled; if (preset == "quarter_res") return nvenc::nvenc_two_pass::quarter_resolution; if (preset == "full_res") return nvenc::nvenc_two_pass::full_resolution; BOOST_LOG(warning) << "config: unknown nvenc_twopass value: " << preset; return nvenc::nvenc_two_pass::quarter_resolution; } } // namespace nv namespace amd { #ifdef __APPLE__ // values accurate as of 27/12/2022, but aren't strictly necessary for MacOS build #define AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED 100 #define AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_QUALITY 30 #define AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_BALANCED 70 #define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED 10 #define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY 0 #define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED 5 #define AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED 1 #define AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY 2 #define AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED 0 #define AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP 0 #define AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR 3 #define AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 2 #define AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 1 #define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP 0 #define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR 3 #define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 2 #define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 1 #define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP 0 #define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR 1 #define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 2 #define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 3 #define AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING 0 #define AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY 1 #define AMF_VIDEO_ENCODER_AV1_USAGE_ULTRA_LOW_LATENCY 2 #define AMF_VIDEO_ENCODER_AV1_USAGE_WEBCAM 3 #define AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY_HIGH_QUALITY 5 #define AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING 0 #define AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY 1 #define AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY 2 #define AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM 3 #define AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY_HIGH_QUALITY 5 #define AMF_VIDEO_ENCODER_USAGE_TRANSCODING 0 #define AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY 1 #define AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY 2 #define AMF_VIDEO_ENCODER_USAGE_WEBCAM 3 #define AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY 5 #define AMF_VIDEO_ENCODER_UNDEFINED 0 #define AMF_VIDEO_ENCODER_CABAC 1 #define AMF_VIDEO_ENCODER_CALV 2 #else #ifdef _GLIBCXX_USE_C99_INTTYPES #undef _GLIBCXX_USE_C99_INTTYPES #endif #include #include #include #endif enum class quality_av1_e : int { speed = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED, quality = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_QUALITY, balanced = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_BALANCED }; enum class quality_hevc_e : int { speed = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED, quality = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY, balanced = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED }; enum class quality_h264_e : int { speed = AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED, quality = AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY, balanced = AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED }; enum class rc_av1_e : int { cbr = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR, cqp = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP, vbr_latency = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR, vbr_peak = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }; enum class rc_hevc_e : int { cbr = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR, cqp = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP, vbr_latency = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR, vbr_peak = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }; enum class rc_h264_e : int { cbr = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR, cqp = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP, vbr_latency = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR, vbr_peak = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }; enum class usage_av1_e : int { transcoding = AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING, webcam = AMF_VIDEO_ENCODER_AV1_USAGE_WEBCAM, lowlatency_high_quality = AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY_HIGH_QUALITY, lowlatency = AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY, ultralowlatency = AMF_VIDEO_ENCODER_AV1_USAGE_ULTRA_LOW_LATENCY }; enum class usage_hevc_e : int { transcoding = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING, webcam = AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM, lowlatency_high_quality = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY_HIGH_QUALITY, lowlatency = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY, ultralowlatency = AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY }; enum class usage_h264_e : int { transcoding = AMF_VIDEO_ENCODER_USAGE_TRANSCODING, webcam = AMF_VIDEO_ENCODER_USAGE_WEBCAM, lowlatency_high_quality = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY, lowlatency = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY, ultralowlatency = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }; enum coder_e : int { _auto = AMF_VIDEO_ENCODER_UNDEFINED, cabac = AMF_VIDEO_ENCODER_CABAC, cavlc = AMF_VIDEO_ENCODER_CALV }; template std::optional quality_from_view(const std::string_view &quality_type, const std::optional(&original)) { #define _CONVERT_(x) \ if (quality_type == #x##sv) return (int) T::x _CONVERT_(balanced); _CONVERT_(quality); _CONVERT_(speed); #undef _CONVERT_ return original; } template std::optional rc_from_view(const std::string_view &rc, const std::optional(&original)) { #define _CONVERT_(x) \ if (rc == #x##sv) return (int) T::x _CONVERT_(cbr); _CONVERT_(cqp); _CONVERT_(vbr_latency); _CONVERT_(vbr_peak); #undef _CONVERT_ return original; } template std::optional usage_from_view(const std::string_view &usage, const std::optional(&original)) { #define _CONVERT_(x) \ if (usage == #x##sv) return (int) T::x _CONVERT_(lowlatency); _CONVERT_(lowlatency_high_quality); _CONVERT_(transcoding); _CONVERT_(ultralowlatency); _CONVERT_(webcam); #undef _CONVERT_ return original; } int coder_from_view(const std::string_view &coder) { if (coder == "auto"sv) return _auto; if (coder == "cabac"sv || coder == "ac"sv) return cabac; if (coder == "cavlc"sv || coder == "vlc"sv) return cavlc; return _auto; } } // namespace amd namespace qsv { enum preset_e : int { veryslow = 1, ///< veryslow preset slower = 2, ///< slower preset slow = 3, ///< slow preset medium = 4, ///< medium preset fast = 5, ///< fast preset faster = 6, ///< faster preset veryfast = 7 ///< veryfast preset }; enum cavlc_e : int { _auto = false, ///< Auto enabled = true, ///< Enabled disabled = false ///< Disabled }; std::optional preset_from_view(const std::string_view &preset) { #define _CONVERT_(x) \ if (preset == #x##sv) return x _CONVERT_(veryslow); _CONVERT_(slower); _CONVERT_(slow); _CONVERT_(medium); _CONVERT_(fast); _CONVERT_(faster); _CONVERT_(veryfast); #undef _CONVERT_ return std::nullopt; } std::optional coder_from_view(const std::string_view &coder) { if (coder == "auto"sv) return _auto; if (coder == "cabac"sv || coder == "ac"sv) return disabled; if (coder == "cavlc"sv || coder == "vlc"sv) return enabled; return std::nullopt; } } // namespace qsv namespace vt { enum coder_e : int { _auto = 0, cabac, cavlc }; int coder_from_view(const std::string_view &coder) { if (coder == "auto"sv) return _auto; if (coder == "cabac"sv || coder == "ac"sv) return cabac; if (coder == "cavlc"sv || coder == "vlc"sv) return cavlc; return -1; } int allow_software_from_view(const std::string_view &software) { if (software == "allowed"sv || software == "forced") return 1; return 0; } int force_software_from_view(const std::string_view &software) { if (software == "forced") return 1; return 0; } int rt_from_view(const std::string_view &rt) { if (rt == "disabled" || rt == "off" || rt == "0") return 0; return 1; } } // namespace vt video_t video { 28, // qp 0, // hevc_mode 0, // av1_mode 2, // min_threads { "superfast"s, // preset "zerolatency"s, // tune 11, // superfast }, // software {}, // nv true, // nv_realtime_hags true, // nv_opengl_vulkan_on_dxgi true, // nv_sunshine_high_power_mode {}, // nv_legacy { qsv::medium, // preset qsv::_auto, // cavlc false, // slow_hevc }, // qsv { (int) amd::usage_h264_e::ultralowlatency, // usage (h264) (int) amd::usage_hevc_e::ultralowlatency, // usage (hevc) (int) amd::usage_av1_e::ultralowlatency, // usage (av1) (int) amd::rc_h264_e::vbr_latency, // rate control (h264) (int) amd::rc_hevc_e::vbr_latency, // rate control (hevc) (int) amd::rc_av1_e::vbr_latency, // rate control (av1) 0, // enforce_hrd (int) amd::quality_h264_e::balanced, // quality (h264) (int) amd::quality_hevc_e::balanced, // quality (hevc) (int) amd::quality_av1_e::balanced, // quality (av1) 0, // preanalysis 1, // vbaq (int) amd::coder_e::_auto, // coder }, // amd { 0, 0, 1, -1, }, // vt {}, // capture {}, // encoder {}, // adapter_name {}, // output_name }; audio_t audio { {}, // audio_sink {}, // virtual_sink true, // install_steam_drivers }; stream_t stream { 10s, // ping_timeout APPS_JSON_PATH, 20, // fecPercentage 1, // channels ENCRYPTION_MODE_NEVER, // lan_encryption_mode ENCRYPTION_MODE_OPPORTUNISTIC, // wan_encryption_mode }; nvhttp_t nvhttp { "lan", // origin web manager PRIVATE_KEY_FILE, CERTIFICATE_FILE, boost::asio::ip::host_name(), // sunshine_name, "sunshine_state.json"s, // file_state {}, // external_ip { "352x240"s, "480x360"s, "858x480"s, "1280x720"s, "1920x1080"s, "2560x1080"s, "2560x1440"s, "3440x1440"s, "1920x1200"s, "3840x2160"s, "3840x1600"s, }, // supported resolutions { 10, 30, 60, 90, 120 }, // supported fps }; sunshine_t sunshine { "en", // locale 2, // min_log_level 0, // flags {}, // User file {}, // Username {}, // Password {}, // Password Salt platf::appdata().string() + "/sunshine.conf", // config file {}, // cmd args 47989, // Base port number "ipv4", // Address family platf::appdata().string() + "/sunshine.log", // log file {}, // prep commands }; } // namespace config