diff --git a/app/backend/nvcomputer.cpp b/app/backend/nvcomputer.cpp index 30ec9a9a..0b80e657 100644 --- a/app/backend/nvcomputer.cpp +++ b/app/backend/nvcomputer.cpp @@ -21,6 +21,7 @@ #define SER_APPLIST "apps" #define SER_SRVCERT "srvcert" #define SER_CUSTOMNAME "customname" +#define SER_NVIDIASOFTWARE "nvidiasw" NvComputer::NvComputer(QSettings& settings) { @@ -37,6 +38,7 @@ NvComputer::NvComputer(QSettings& settings) this->manualAddress = NvAddress(settings.value(SER_MANUALADDR).toString(), settings.value(SER_MANUALPORT, QVariant(DEFAULT_HTTP_PORT)).toUInt()); this->serverCert = QSslCertificate(settings.value(SER_SRVCERT).toByteArray()); + this->isNvidiaServerSoftware = settings.value(SER_NVIDIASOFTWARE).toBool(); int appCount = settings.beginReadArray(SER_APPLIST); this->appList.reserve(appCount); @@ -89,6 +91,7 @@ void NvComputer::serialize(QSettings& settings) const settings.setValue(SER_MANUALADDR, manualAddress.address()); settings.setValue(SER_MANUALPORT, manualAddress.port()); settings.setValue(SER_SRVCERT, serverCert.toPem()); + settings.setValue(SER_NVIDIASOFTWARE, isNvidiaServerSoftware); // Avoid deleting an existing applist if we couldn't get one if (!appList.isEmpty()) { @@ -177,6 +180,11 @@ NvComputer::NvComputer(NvHTTP& http, QString serverInfo) this->remoteAddress = NvAddress(); } + // Real Nvidia host software (GeForce Experience and RTX Experience) both use the 'Mjolnir' + // codename in the state field and no version of Sunshine does. We can use this to bypass + // some assumptions about Nvidia hardware that don't apply to Sunshine hosts. + this->isNvidiaServerSoftware = NvHTTP::getXmlString(serverInfo, "state").contains("MJOLNIR"); + this->pairState = NvHTTP::getXmlString(serverInfo, "PairStatus") == "1" ? PS_PAIRED : PS_NOT_PAIRED; this->currentGameId = NvHTTP::getCurrentGame(serverInfo); @@ -473,6 +481,7 @@ bool NvComputer::update(const NvComputer& that) ASSIGN_IF_CHANGED(gfeVersion); ASSIGN_IF_CHANGED(appVersion); ASSIGN_IF_CHANGED(isSupportedServerVersion); + ASSIGN_IF_CHANGED(isNvidiaServerSoftware); ASSIGN_IF_CHANGED(maxLumaPixelsHEVC); ASSIGN_IF_CHANGED(gpuModel); ASSIGN_IF_CHANGED_AND_NONNULL(serverCert); diff --git a/app/backend/nvcomputer.h b/app/backend/nvcomputer.h index 5a68ef67..bab7fe5c 100644 --- a/app/backend/nvcomputer.h +++ b/app/backend/nvcomputer.h @@ -83,6 +83,7 @@ public: QString uuid; QSslCertificate serverCert; QVector appList; + bool isNvidiaServerSoftware; // Synchronization mutable QReadWriteLock lock; diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index 52f85592..e894c4ee 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -798,7 +798,10 @@ bool Session::validateLaunch(SDL_Window* testWindow) } // NVENC will fail to initialize when using dimensions over 4096 and H.264. - if (m_StreamConfig.width > 4096 || m_StreamConfig.height > 4096) { + // + // However, if we aren't using Nvidia hosting software, don't assume anything + // about H.264 capabilities by using HEVC Main10 support. It will likely be wrong. + if ((m_StreamConfig.width > 4096 || m_StreamConfig.height > 4096) && m_Computer->isNvidiaServerSoftware) { // Pascal added support for 8K HEVC encoding support. Maxwell 2 could encode HEVC but only up to 4K. // We can't directly identify Pascal, but we can look for HEVC Main10 which was added in the same generation. if (m_Computer->maxLumaPixelsHEVC == 0 || !(m_Computer->serverCodecModeSupport & 0x200)) {