mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-03 08:15:37 +00:00
Add additional serverinfo attributes and check for 4K compatibility
This commit is contained in:
parent
d0375a458a
commit
5a04a256e0
@ -10,7 +10,6 @@
|
|||||||
#define SER_NAME "hostname"
|
#define SER_NAME "hostname"
|
||||||
#define SER_UUID "uuid"
|
#define SER_UUID "uuid"
|
||||||
#define SER_MAC "mac"
|
#define SER_MAC "mac"
|
||||||
#define SER_CODECSUPP "codecsupport"
|
|
||||||
#define SER_LOCALADDR "localaddress"
|
#define SER_LOCALADDR "localaddress"
|
||||||
#define SER_REMOTEADDR "remoteaddress"
|
#define SER_REMOTEADDR "remoteaddress"
|
||||||
#define SER_MANUALADDR "manualaddress"
|
#define SER_MANUALADDR "manualaddress"
|
||||||
@ -25,7 +24,6 @@ NvComputer::NvComputer(QSettings& settings)
|
|||||||
this->name = settings.value(SER_NAME).toString();
|
this->name = settings.value(SER_NAME).toString();
|
||||||
this->uuid = settings.value(SER_UUID).toString();
|
this->uuid = settings.value(SER_UUID).toString();
|
||||||
this->macAddress = settings.value(SER_MAC).toByteArray();
|
this->macAddress = settings.value(SER_MAC).toByteArray();
|
||||||
this->serverCodecModeSupport = settings.value(SER_CODECSUPP).toInt();
|
|
||||||
this->localAddress = settings.value(SER_LOCALADDR).toString();
|
this->localAddress = settings.value(SER_LOCALADDR).toString();
|
||||||
this->remoteAddress = settings.value(SER_REMOTEADDR).toString();
|
this->remoteAddress = settings.value(SER_REMOTEADDR).toString();
|
||||||
this->manualAddress = settings.value(SER_MANUALADDR).toString();
|
this->manualAddress = settings.value(SER_MANUALADDR).toString();
|
||||||
@ -61,7 +59,6 @@ NvComputer::serialize(QSettings& settings)
|
|||||||
settings.setValue(SER_NAME, name);
|
settings.setValue(SER_NAME, name);
|
||||||
settings.setValue(SER_UUID, uuid);
|
settings.setValue(SER_UUID, uuid);
|
||||||
settings.setValue(SER_MAC, macAddress);
|
settings.setValue(SER_MAC, macAddress);
|
||||||
settings.setValue(SER_CODECSUPP, serverCodecModeSupport);
|
|
||||||
settings.setValue(SER_LOCALADDR, localAddress);
|
settings.setValue(SER_LOCALADDR, localAddress);
|
||||||
settings.setValue(SER_REMOTEADDR, remoteAddress);
|
settings.setValue(SER_REMOTEADDR, remoteAddress);
|
||||||
settings.setValue(SER_MANUALADDR, manualAddress);
|
settings.setValue(SER_MANUALADDR, manualAddress);
|
||||||
@ -112,6 +109,21 @@ NvComputer::NvComputer(QString address, QString serverInfo)
|
|||||||
this->serverCodecModeSupport = 0;
|
this->serverCodecModeSupport = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString maxLumaPixelsHEVC = NvHTTP::getXmlString(serverInfo, "MaxLumaPixelsHEVC");
|
||||||
|
if (!maxLumaPixelsHEVC.isNull()) {
|
||||||
|
this->maxLumaPixelsHEVC = maxLumaPixelsHEVC.toInt();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this->maxLumaPixelsHEVC = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->displayModes = NvHTTP::getDisplayModeList(serverInfo);
|
||||||
|
std::stable_sort(this->displayModes.begin(), this->displayModes.end(),
|
||||||
|
[](const NvDisplayMode& mode1, const NvDisplayMode& mode2) {
|
||||||
|
return mode1.width * mode1.height * mode1.refreshRate <
|
||||||
|
mode2.width * mode2.height * mode2.refreshRate;
|
||||||
|
});
|
||||||
|
|
||||||
this->localAddress = NvHTTP::getXmlString(serverInfo, "LocalIP");
|
this->localAddress = NvHTTP::getXmlString(serverInfo, "LocalIP");
|
||||||
this->remoteAddress = NvHTTP::getXmlString(serverInfo, "ExternalIP");
|
this->remoteAddress = NvHTTP::getXmlString(serverInfo, "ExternalIP");
|
||||||
this->pairState = NvHTTP::getXmlString(serverInfo, "PairStatus") == "1" ?
|
this->pairState = NvHTTP::getXmlString(serverInfo, "PairStatus") == "1" ?
|
||||||
@ -249,7 +261,9 @@ bool NvComputer::update(NvComputer& that)
|
|||||||
ASSIGN_IF_CHANGED(state);
|
ASSIGN_IF_CHANGED(state);
|
||||||
ASSIGN_IF_CHANGED(gfeVersion);
|
ASSIGN_IF_CHANGED(gfeVersion);
|
||||||
ASSIGN_IF_CHANGED(appVersion);
|
ASSIGN_IF_CHANGED(appVersion);
|
||||||
|
ASSIGN_IF_CHANGED(maxLumaPixelsHEVC);
|
||||||
ASSIGN_IF_CHANGED_AND_NONEMPTY(appList);
|
ASSIGN_IF_CHANGED_AND_NONEMPTY(appList);
|
||||||
|
ASSIGN_IF_CHANGED_AND_NONEMPTY(displayModes);
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,9 @@ public:
|
|||||||
int currentGameId;
|
int currentGameId;
|
||||||
QString gfeVersion;
|
QString gfeVersion;
|
||||||
QString appVersion;
|
QString appVersion;
|
||||||
|
QVector<NvDisplayMode> displayModes;
|
||||||
|
int maxLumaPixelsHEVC;
|
||||||
|
int serverCodecModeSupport;
|
||||||
|
|
||||||
// Persisted traits
|
// Persisted traits
|
||||||
QString localAddress;
|
QString localAddress;
|
||||||
@ -66,7 +69,6 @@ public:
|
|||||||
QByteArray macAddress;
|
QByteArray macAddress;
|
||||||
QString name;
|
QString name;
|
||||||
QString uuid;
|
QString uuid;
|
||||||
int serverCodecModeSupport;
|
|
||||||
QVector<NvApp> appList;
|
QVector<NvApp> appList;
|
||||||
|
|
||||||
// Synchronization
|
// Synchronization
|
||||||
|
@ -182,6 +182,33 @@ NvHTTP::quitApp()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<NvDisplayMode>
|
||||||
|
NvHTTP::getDisplayModeList(QString serverInfo)
|
||||||
|
{
|
||||||
|
QXmlStreamReader xmlReader(serverInfo);
|
||||||
|
QVector<NvDisplayMode> modes;
|
||||||
|
|
||||||
|
while (!xmlReader.atEnd()) {
|
||||||
|
while (xmlReader.readNextStartElement()) {
|
||||||
|
QStringRef name = xmlReader.name();
|
||||||
|
if (xmlReader.name() == "DisplayMode") {
|
||||||
|
modes.append(NvDisplayMode());
|
||||||
|
}
|
||||||
|
else if (xmlReader.name() == "Width") {
|
||||||
|
modes.last().width = xmlReader.readElementText().toInt();
|
||||||
|
}
|
||||||
|
else if (xmlReader.name() == "Height") {
|
||||||
|
modes.last().height = xmlReader.readElementText().toInt();
|
||||||
|
}
|
||||||
|
else if (xmlReader.name() == "RefreshRate") {
|
||||||
|
modes.last().refreshRate = xmlReader.readElementText().toInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return modes;
|
||||||
|
}
|
||||||
|
|
||||||
QVector<NvApp>
|
QVector<NvApp>
|
||||||
NvHTTP::getAppList()
|
NvHTTP::getAppList()
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,21 @@ public:
|
|||||||
|
|
||||||
Q_DECLARE_METATYPE(NvApp)
|
Q_DECLARE_METATYPE(NvApp)
|
||||||
|
|
||||||
|
class NvDisplayMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool operator==(const NvDisplayMode& other) const
|
||||||
|
{
|
||||||
|
return width == other.width &&
|
||||||
|
height == other.height &&
|
||||||
|
refreshRate == other.refreshRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int refreshRate;
|
||||||
|
};
|
||||||
|
|
||||||
class GfeHttpResponseException : public std::exception
|
class GfeHttpResponseException : public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -117,6 +132,10 @@ public:
|
|||||||
QImage
|
QImage
|
||||||
getBoxArt(int appId);
|
getBoxArt(int appId);
|
||||||
|
|
||||||
|
static
|
||||||
|
QVector<NvDisplayMode>
|
||||||
|
getDisplayModeList(QString serverInfo);
|
||||||
|
|
||||||
QUrl m_BaseUrlHttp;
|
QUrl m_BaseUrlHttp;
|
||||||
QUrl m_BaseUrlHttps;
|
QUrl m_BaseUrlHttps;
|
||||||
private:
|
private:
|
||||||
|
@ -41,9 +41,9 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(VideoDecoderSelection)
|
Q_ENUM(VideoDecoderSelection)
|
||||||
|
|
||||||
Q_PROPERTY(int width MEMBER width NOTIFY resolutionOrFpsChanged)
|
Q_PROPERTY(int width MEMBER width NOTIFY displayModeChanged)
|
||||||
Q_PROPERTY(int height MEMBER height NOTIFY resolutionOrFpsChanged)
|
Q_PROPERTY(int height MEMBER height NOTIFY displayModeChanged)
|
||||||
Q_PROPERTY(int fps MEMBER fps NOTIFY resolutionOrFpsChanged)
|
Q_PROPERTY(int fps MEMBER fps NOTIFY displayModeChanged)
|
||||||
Q_PROPERTY(int bitrateKbps MEMBER bitrateKbps NOTIFY bitrateChanged)
|
Q_PROPERTY(int bitrateKbps MEMBER bitrateKbps NOTIFY bitrateChanged)
|
||||||
Q_PROPERTY(bool fullScreen MEMBER fullScreen NOTIFY fullScreenChanged)
|
Q_PROPERTY(bool fullScreen MEMBER fullScreen NOTIFY fullScreenChanged)
|
||||||
Q_PROPERTY(bool gameOptimizations MEMBER gameOptimizations NOTIFY gameOptimizationsChanged)
|
Q_PROPERTY(bool gameOptimizations MEMBER gameOptimizations NOTIFY gameOptimizationsChanged)
|
||||||
@ -67,7 +67,7 @@ public:
|
|||||||
VideoDecoderSelection videoDecoderSelection;
|
VideoDecoderSelection videoDecoderSelection;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void resolutionOrFpsChanged();
|
void displayModeChanged();
|
||||||
void bitrateChanged();
|
void bitrateChanged();
|
||||||
void fullScreenChanged();
|
void fullScreenChanged();
|
||||||
void gameOptimizationsChanged();
|
void gameOptimizationsChanged();
|
||||||
|
@ -136,9 +136,20 @@ Session::Session(NvComputer* computer, NvApp& app)
|
|||||||
|
|
||||||
bool Session::validateLaunch()
|
bool Session::validateLaunch()
|
||||||
{
|
{
|
||||||
NvHTTP http(m_Computer->activeAddress);
|
|
||||||
QStringList warningList;
|
QStringList warningList;
|
||||||
|
|
||||||
|
if (m_StreamConfig.supportsHevc) {
|
||||||
|
if (m_Preferences.videoCodecConfig == StreamingPreferences::VCC_FORCE_HEVC ||
|
||||||
|
m_Preferences.videoCodecConfig == StreamingPreferences::VCC_FORCE_HEVC_HDR) {
|
||||||
|
if (m_Computer->maxLumaPixelsHEVC == 0) {
|
||||||
|
emit displayLaunchWarning("Your host PC GPU doesn't support HEVC. "
|
||||||
|
"A GeForce GTX 900-series (Maxwell) or later GPU is required for HEVC streaming.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Validate HEVC support based on decoder caps
|
||||||
|
}
|
||||||
|
|
||||||
if (m_StreamConfig.enableHdr) {
|
if (m_StreamConfig.enableHdr) {
|
||||||
// Turn HDR back off unless all criteria are met.
|
// Turn HDR back off unless all criteria are met.
|
||||||
m_StreamConfig.enableHdr = false;
|
m_StreamConfig.enableHdr = false;
|
||||||
@ -161,16 +172,22 @@ bool Session::validateLaunch()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_StreamConfig.width >= 3840) {
|
if (m_StreamConfig.width >= 3840) {
|
||||||
if (m_StreamConfig.fps >= 60) {
|
// Only allow 4K on GFE 3.x+
|
||||||
// TODO: Validate 4K60 support based on serverinfo
|
if (m_Computer->gfeVersion.isNull() || m_Computer->gfeVersion.startsWith("2.")) {
|
||||||
}
|
emit displayLaunchWarning("GeForce Experience 3.0 or higher is required for 4K streaming.");
|
||||||
else {
|
|
||||||
// TODO: Validate 4K30 support based on serverinfo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_StreamConfig.supportsHevc) {
|
m_StreamConfig.width = 1920;
|
||||||
// TODO: Validate HEVC support based on decoder caps
|
m_StreamConfig.height = 1080;
|
||||||
|
}
|
||||||
|
// This list is sorted from least to greatest
|
||||||
|
else if (m_Computer->displayModes.last().width < 3840 ||
|
||||||
|
(m_Computer->displayModes.last().refreshRate < 60 && m_StreamConfig.fps >= 60)) {
|
||||||
|
emit displayLaunchWarning("Your host PC GPU doesn't support 4K streaming. "
|
||||||
|
"A GeForce GTX 900-series (Maxwell) or later GPU is required for 4K streaming.");
|
||||||
|
|
||||||
|
m_StreamConfig.width = 1920;
|
||||||
|
m_StreamConfig.height = 1080;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always allow the launch to proceed for now
|
// Always allow the launch to proceed for now
|
||||||
|
Loading…
x
Reference in New Issue
Block a user