Merge branch 'master' of https://github.com/LizardByte/Sunshine
# Conflicts: # .github/workflows/ci-copr.yml # .github/workflows/ci-flatpak.yml # .github/workflows/ci-homebrew.yml # .github/workflows/ci-linux.yml # .github/workflows/ci-windows.yml # .github/workflows/ci.yml # .github/workflows/localize.yml # README.md # scripts/icons/convert_and_pack.sh # src/config.cpp # src/config.h # src/confighttp.cpp # src/logging.cpp # src/video.cpp # src_assets/common/assets/web/config.html # src_assets/common/assets/web/public/assets/locale/en.json # src_assets/common/assets/web/public/assets/locale/it.json # src_assets/windows/misc/gamepad/install-gamepad.bat # third-party/build-deps # third-party/moonlight-common-c # tools/CMakeLists.txt
This commit is contained in:
@@ -34,7 +34,7 @@
|
||||
#include "platform/windows/utils.h"
|
||||
#endif
|
||||
|
||||
#ifndef __APPLE__
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
// For NVENC legacy constants
|
||||
#include <ffnvcodec/nvEncodeAPI.h>
|
||||
#endif
|
||||
@@ -511,6 +511,7 @@ namespace config {
|
||||
}, // display_device
|
||||
|
||||
0, // max_bitrate
|
||||
0, // minimum_fps_target (0 = framerate)
|
||||
|
||||
"1920x1080x60", // fallback_mode
|
||||
false, // isolated Display
|
||||
@@ -1085,9 +1086,12 @@ namespace config {
|
||||
}
|
||||
|
||||
void apply_config(std::unordered_map<std::string, std::string> &&vars) {
|
||||
#ifndef __ANDROID__
|
||||
// TODO: Android can possibly support this
|
||||
if (!fs::exists(stream.file_apps.c_str())) {
|
||||
fs::copy_file(SUNSHINE_ASSETS_DIR "/apps.json", stream.file_apps);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (auto &[name, val] : vars) {
|
||||
#ifdef _WIN32
|
||||
@@ -1121,7 +1125,7 @@ namespace config {
|
||||
bool_f(vars, "nvenc_opengl_vulkan_on_dxgi", video.nv_opengl_vulkan_on_dxgi);
|
||||
bool_f(vars, "nvenc_latency_over_power", video.nv_sunshine_high_power_mode);
|
||||
|
||||
#ifndef __APPLE__
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
video.nv_legacy.preset = video.nv.quality_preset + 11;
|
||||
video.nv_legacy.multipass = video.nv.two_pass == nvenc::nvenc_two_pass::quarter_resolution ? NV_ENC_TWO_PASS_QUARTER_RESOLUTION :
|
||||
video.nv.two_pass == nvenc::nvenc_two_pass::full_resolution ? NV_ENC_TWO_PASS_FULL_RESOLUTION :
|
||||
@@ -1198,6 +1202,8 @@ namespace config {
|
||||
}
|
||||
|
||||
int_f(vars, "max_bitrate", video.max_bitrate);
|
||||
double_between_f(vars, "minimum_fps_target", video.minimum_fps_target, {0.0, 1000.0});
|
||||
|
||||
string_f(vars, "fallback_mode", video.fallback_mode);
|
||||
bool_f(vars, "isolated_virtual_display_option", video.isolated_virtual_display_option);
|
||||
bool_f(vars, "ignore_encoder_probe_failure", video.ignore_encoder_probe_failure);
|
||||
|
||||
@@ -144,6 +144,7 @@ namespace config {
|
||||
} dd;
|
||||
|
||||
int max_bitrate; // Maximum bitrate, sets ceiling in kbps for bitrate requested from client
|
||||
double minimum_fps_target; ///< Lowest framerate that will be used when streaming. Range 0-1000, 0 = half of client's requested framerate.
|
||||
|
||||
std::string fallback_mode;
|
||||
bool isolated_virtual_display_option;
|
||||
|
||||
@@ -16,11 +16,17 @@
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/sinks.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <display_device/logging.h>
|
||||
|
||||
// local includes
|
||||
#include "logging.h"
|
||||
|
||||
// conditional includes
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#else
|
||||
#include <display_device/logging.h>
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/log.h>
|
||||
}
|
||||
@@ -98,6 +104,48 @@ namespace logging {
|
||||
os << "["sv << std::put_time(<, "%Y-%m-%d %H:%M:%S.") << boost::format("%03u") % ms.count() << "]: "sv
|
||||
<< log_type << view.attribute_values()[message].extract<std::string>();
|
||||
}
|
||||
#ifdef __ANDROID__
|
||||
namespace sinks = boost::log::sinks;
|
||||
namespace expr = boost::log::expressions;
|
||||
|
||||
void android_log(const std::string &message, int severity) {
|
||||
android_LogPriority android_priority;
|
||||
switch (severity) {
|
||||
case 0:
|
||||
android_priority = ANDROID_LOG_VERBOSE;
|
||||
break;
|
||||
case 1:
|
||||
android_priority = ANDROID_LOG_DEBUG;
|
||||
break;
|
||||
case 2:
|
||||
android_priority = ANDROID_LOG_INFO;
|
||||
break;
|
||||
case 3:
|
||||
android_priority = ANDROID_LOG_WARN;
|
||||
break;
|
||||
case 4:
|
||||
android_priority = ANDROID_LOG_ERROR;
|
||||
break;
|
||||
case 5:
|
||||
android_priority = ANDROID_LOG_FATAL;
|
||||
break;
|
||||
default:
|
||||
android_priority = ANDROID_LOG_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
__android_log_print(android_priority, "Sunshine", "%s", message.c_str());
|
||||
}
|
||||
|
||||
// custom sink backend for android
|
||||
struct android_sink_backend: public sinks::basic_sink_backend<sinks::concurrent_feeding> {
|
||||
void consume(const bl::record_view &rec) {
|
||||
int log_sev = rec[severity].get();
|
||||
const std::string log_msg = rec[expr::smessage].get();
|
||||
// log to android
|
||||
android_log(log_msg, log_sev);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
[[nodiscard]] std::unique_ptr<deinit_t> init(int min_log_level, const std::string &log_file) {
|
||||
if (sink) {
|
||||
@@ -120,15 +168,18 @@ namespace logging {
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
setup_av_logging(min_log_level);
|
||||
setup_libdisplaydevice_logging(min_log_level);
|
||||
#endif
|
||||
|
||||
sink = boost::make_shared<text_sink>();
|
||||
|
||||
#ifndef SUNSHINE_TESTS
|
||||
boost::shared_ptr<std::ostream> stream {&std::cout, boost::null_deleter()};
|
||||
sink->locked_backend()->add_stream(stream);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
sink->locked_backend()->add_stream(boost::make_shared<std::ofstream>(log_file));
|
||||
sink->set_filter(severity >= min_log_level);
|
||||
sink->set_formatter(&formatter);
|
||||
@@ -138,9 +189,15 @@ namespace logging {
|
||||
sink->locked_backend()->auto_flush(true);
|
||||
|
||||
bl::core::get()->add_sink(sink);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
auto android_sink = boost::make_shared<sinks::synchronous_sink<android_sink_backend>>();
|
||||
bl::core::get()->add_sink(android_sink);
|
||||
#endif
|
||||
return std::make_unique<deinit_t>();
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
void setup_av_logging(int min_log_level) {
|
||||
if (min_log_level >= 1) {
|
||||
av_log_set_level(AV_LOG_QUIET);
|
||||
@@ -198,6 +255,7 @@ namespace logging {
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
void log_flush() {
|
||||
if (sink) {
|
||||
|
||||
@@ -1922,10 +1922,12 @@ namespace video {
|
||||
}
|
||||
});
|
||||
|
||||
// set minimum frame time based on client-requested target framerate
|
||||
auto minimum_frame_time = std::chrono::nanoseconds(1000ms) * 1000 / config.encodingFramerate;
|
||||
// set minimum frame time based on client-requested target framerate// set max frame time based on client-requested target framerate.
|
||||
double minimum_fps_target = (config::video.minimum_fps_target > 0.0) ? config::video.minimum_fps_target : config.encodingFramerate;
|
||||
auto max_frametime = std::chrono::nanoseconds(1000ms) * 1000 / minimum_fps_target;
|
||||
auto encode_frame_threshold = std::chrono::nanoseconds(1000ms) * 1000 / config.encodingFramerate;
|
||||
auto frame_variation_threshold = encode_frame_threshold / 4;
|
||||
BOOST_LOG(info) << "Minimum FPS target set to ~"sv << (minimum_fps_target / 2) << "fps ("sv << max_frametime.count() * 2 << "ns)"sv;
|
||||
BOOST_LOG(info) << "Encoding Frame threshold: "sv << encode_frame_threshold;
|
||||
|
||||
auto shutdown_event = mail->event<bool>(mail::shutdown);
|
||||
@@ -1997,7 +1999,7 @@ namespace video {
|
||||
|
||||
// Encode at a minimum FPS to avoid image quality issues with static content
|
||||
if (!requested_idr_frame || images->peek()) {
|
||||
if (auto img = images->pop(minimum_frame_time)) {
|
||||
if (auto img = images->pop(max_frametime)) {
|
||||
frame_timestamp = img->frame_timestamp;
|
||||
// If new frame comes in way too fast, just drop
|
||||
if (*frame_timestamp < (next_frame_start - frame_variation_threshold)) {
|
||||
|
||||
Reference in New Issue
Block a user