diff --git a/assets/sunshine.conf b/assets/sunshine.conf index 1b82910e..103f44b0 100644 --- a/assets/sunshine.conf +++ b/assets/sunshine.conf @@ -78,7 +78,7 @@ # ] # How long to wait in milliseconds for data from moonlight before shutting down the stream -# ping_timeout = 2000 +# ping_timeout = 10000 # The file where configuration for the different applications that Sunshine can run during a stream # file_apps = apps.json diff --git a/assets/web/config.html b/assets/web/config.html index a4a39c58..f9c5380f 100644 --- a/assets/web/config.html +++ b/assets/web/config.html @@ -55,7 +55,7 @@
-
How long to wait in milliseconds for data from moonlight before shutting down the stream
@@ -528,7 +528,7 @@ } if (this.platform == "linux") { this.tabs = this.tabs.filter(el => { - return el.id !== "nv" && el.id !== "amd"; + return el.id !== "amd"; }); } diff --git a/sunshine/config.cpp b/sunshine/config.cpp index b7c258f3..f8cc735d 100644 --- a/sunshine/config.cpp +++ b/sunshine/config.cpp @@ -176,7 +176,7 @@ video_t video { audio_t audio {}; stream_t stream { - 2s, // ping_timeout + 10s, // ping_timeout APPS_JSON_PATH, diff --git a/sunshine/nvhttp.cpp b/sunshine/nvhttp.cpp index bef7cd67..cffc65dd 100644 --- a/sunshine/nvhttp.cpp +++ b/sunshine/nvhttp.cpp @@ -34,7 +34,7 @@ using namespace std::literals; namespace nvhttp { constexpr auto VERSION = "7.1.431.0"; -constexpr auto GFE_VERSION = "3.12.0.1"; +constexpr auto GFE_VERSION = "3.23.0.74"; namespace fs = std::filesystem; namespace pt = boost::property_tree; diff --git a/sunshine/platform/common.h b/sunshine/platform/common.h index e866ce4b..0699d886 100644 --- a/sunshine/platform/common.h +++ b/sunshine/platform/common.h @@ -75,6 +75,7 @@ enum class mem_type_e { system, vaapi, dxgi, + cuda, unknown }; diff --git a/sunshine/platform/linux/display.cpp b/sunshine/platform/linux/display.cpp index 867220d3..188974b0 100644 --- a/sunshine/platform/linux/display.cpp +++ b/sunshine/platform/linux/display.cpp @@ -372,7 +372,7 @@ struct shm_attr_t : public x11_attr_t { }; std::shared_ptr display(platf::mem_type_e hwdevice_type) { - if(hwdevice_type != platf::mem_type_e::system && hwdevice_type != platf::mem_type_e::vaapi) { + if(hwdevice_type != platf::mem_type_e::system && hwdevice_type != platf::mem_type_e::vaapi && hwdevice_type != platf::mem_type_e::cuda) { BOOST_LOG(error) << "Could not initialize display with the given hw device type."sv; return nullptr; } diff --git a/sunshine/stream.cpp b/sunshine/stream.cpp index 5352eeed..07aa4b3f 100644 --- a/sunshine/stream.cpp +++ b/sunshine/stream.cpp @@ -512,11 +512,14 @@ std::vector replace(const std::string_view &original, const std::string std::vector replaced; auto begin = std::begin(original); - auto next = std::search(begin, std::end(original), std::begin(old), std::end(old)); + auto end = std::end(original); + auto next = std::search(begin, end, std::begin(old), std::end(old)); std::copy(begin, next, std::back_inserter(replaced)); - std::copy(std::begin(_new), std::end(_new), std::back_inserter(replaced)); - std::copy(next + old.size(), std::end(original), std::back_inserter(replaced)); + if(next != end) { + std::copy(std::begin(_new), std::end(_new), std::back_inserter(replaced)); + std::copy(next + old.size(), end, std::back_inserter(replaced)); + } return replaced; } @@ -928,7 +931,7 @@ void videoBroadcastThread(udp::socket &sock) { inspect->packet.flags |= FLAG_EOF; } - inspect->rtp.header = FLAG_EXTENSION; + inspect->rtp.header = 0x80 | FLAG_EXTENSION; inspect->rtp.sequenceNumber = util::endian::big(lowseq + x); } diff --git a/sunshine/video.cpp b/sunshine/video.cpp index 8313fb0c..59f3a1ec 100644 --- a/sunshine/video.cpp +++ b/sunshine/video.cpp @@ -71,6 +71,7 @@ platf::pix_fmt_e map_pix_fmt(AVPixelFormat fmt); util::Either dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx); util::Either vaapi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx); +util::Either cuda_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx); int hwframe_ctx(ctx_t &ctx, buffer_t &hwdevice, AVPixelFormat format); @@ -402,12 +403,16 @@ void end_capture_async(capture_thread_async_ctx_t &ctx); auto capture_thread_async = safe::make_shared(start_capture_async, end_capture_async); auto capture_thread_sync = safe::make_shared(start_capture_sync, end_capture_sync); -#ifdef _WIN32 static encoder_t nvenc { "nvenc"sv, { (int)nv::profile_h264_e::high, (int)nv::profile_hevc_e::main, (int)nv::profile_hevc_e::main_10 }, +#ifdef _WIN32 AV_HWDEVICE_TYPE_D3D11VA, AV_PIX_FMT_D3D11, +#else + AV_HWDEVICE_TYPE_CUDA, + AV_PIX_FMT_CUDA, +#endif AV_PIX_FMT_NV12, AV_PIX_FMT_P010, { { @@ -432,10 +437,16 @@ static encoder_t nvenc { std::make_optional({ "qp"s, &config::video.qp }), "h264_nvenc"s, }, +#ifdef _WIN32 DEFAULT, dxgi_make_hwdevice_ctx +#else + SYSTEM_MEMORY, + cuda_make_hwdevice_ctx +#endif }; +#ifdef _WIN32 static encoder_t amdvce { "amdvce"sv, { FF_PROFILE_H264_HIGH, FF_PROFILE_HEVC_MAIN }, @@ -537,8 +548,8 @@ static encoder_t vaapi { #endif static std::vector encoders { -#ifdef _WIN32 nvenc, +#ifdef _WIN32 amdvce, #endif #ifdef __linux__ @@ -1649,6 +1660,19 @@ util::Either vaapi_make_hwdevice_ctx(platf::hwdevice_t *base) { return hw_device_buf; } +util::Either cuda_make_hwdevice_ctx(platf::hwdevice_t *base) { + buffer_t hw_device_buf; + + auto status = av_hwdevice_ctx_create(&hw_device_buf, AV_HWDEVICE_TYPE_CUDA, nullptr, nullptr, 0); + if(status < 0) { + char string[AV_ERROR_MAX_STRING_SIZE]; + BOOST_LOG(error) << "Failed to create a CUDA device: "sv << av_make_error_string(string, AV_ERROR_MAX_STRING_SIZE, status); + return -1; + } + + return hw_device_buf; +} + #ifdef _WIN32 } @@ -1716,7 +1740,9 @@ platf::mem_type_e map_dev_type(AVHWDeviceType type) { return platf::mem_type_e::dxgi; case AV_HWDEVICE_TYPE_VAAPI: return platf::mem_type_e::vaapi; - case AV_PICTURE_TYPE_NONE: + case AV_HWDEVICE_TYPE_CUDA: + return platf::mem_type_e::cuda; + case AV_HWDEVICE_TYPE_NONE: return platf::mem_type_e::system; default: return platf::mem_type_e::unknown;