Add support for GFE 3.0.7

This commit is contained in:
Cameron Gutman 2016-10-05 18:45:19 -07:00
parent 9caf3b37ac
commit a14a4a8d60
4 changed files with 75 additions and 10 deletions

View File

@ -32,6 +32,9 @@ public class ConnectionContext {
public int serverGeneration; public int serverGeneration;
// This is the version quad from the appversion tag of /serverinfo
public int[] serverAppVersion;
public VideoFormat negotiatedVideoFormat; public VideoFormat negotiatedVideoFormat;
public int negotiatedWidth, negotiatedHeight; public int negotiatedWidth, negotiatedHeight;
public int negotiatedFps; public int negotiatedFps;

View File

@ -105,7 +105,13 @@ public class NvConnection {
String serverInfo = h.getServerInfo(); String serverInfo = h.getServerInfo();
int majorVersion = h.getServerMajorVersion(serverInfo); context.serverAppVersion = h.getServerAppVersionQuad(serverInfo);
if (context.serverAppVersion == null) {
context.connListener.displayMessage("Server version malformed");
return false;
}
int majorVersion = context.serverAppVersion[0];
LimeLog.info("Server major version: "+majorVersion); LimeLog.info("Server major version: "+majorVersion);
if (majorVersion == 0) { if (majorVersion == 0) {
@ -158,16 +164,23 @@ public class NvConnection {
// Lower resolution to 1080p // Lower resolution to 1080p
context.negotiatedWidth = 1920; context.negotiatedWidth = 1920;
context.negotiatedHeight = 1080; context.negotiatedHeight = 1080;
context.negotiatedFps = context.streamConfig.getRefreshRate();
}
else if (context.streamConfig.getHeight() >= 2160 && context.streamConfig.getRefreshRate() >= 60 && !h.supports4K60(serverInfo)) {
// Client wants 4K 60 FPS but the server can't do it
context.connListener.displayTransientMessage("Your GPU does not support 4K 60 FPS streaming. The stream will be 4K 30 FPS.");
context.negotiatedWidth = context.streamConfig.getWidth();
context.negotiatedHeight = context.streamConfig.getHeight();
context.negotiatedFps = 30;
} }
else { else {
// Take what the client wanted // Take what the client wanted
context.negotiatedWidth = context.streamConfig.getWidth(); context.negotiatedWidth = context.streamConfig.getWidth();
context.negotiatedHeight = context.streamConfig.getHeight(); context.negotiatedHeight = context.streamConfig.getHeight();
context.negotiatedFps = context.streamConfig.getRefreshRate();
} }
// For now, always take the client's FPS request
context.negotiatedFps = context.streamConfig.getRefreshRate();
// //
// Video stream format will be decided during the RTSP handshake // Video stream format will be decided during the RTSP handshake
// //

View File

@ -50,7 +50,13 @@ public class VideoDepacketizer {
this.controlListener = controlListener; this.controlListener = controlListener;
this.nominalPacketDataLength = nominalPacketSize - VideoPacket.HEADER_SIZE; this.nominalPacketDataLength = nominalPacketSize - VideoPacket.HEADER_SIZE;
if (context.serverGeneration >= ConnectionContext.SERVER_GENERATION_5) { if ((context.serverAppVersion[0] > 7) ||
(context.serverAppVersion[0] == 7 && context.serverAppVersion[1] > 1) ||
(context.serverAppVersion[0] == 7 && context.serverAppVersion[1] == 1 && context.serverAppVersion[2] >= 320)) {
// Anything over 7.1.320 should use the 12 byte frame header
frameHeaderOffset = 12;
}
else if (context.serverGeneration >= ConnectionContext.SERVER_GENERATION_5) {
// Gen 5 servers have an 8 byte header in the data portion of the first // Gen 5 servers have an 8 byte header in the data portion of the first
// packet of each frame // packet of each frame
frameHeaderOffset = 8; frameHeaderOffset = 8;

View File

@ -402,6 +402,30 @@ public class NvHTTP {
return false; return false;
} }
public boolean supports4K60(String serverInfo) throws XmlPullParserException, IOException {
// If we don't support 4K at all, bail early
if (!supports4K(serverInfo)) {
return false;
}
// serverinfo returns supported resolutions in descending order, so getting the first
// refresh rate will give us whether we support 4K60. If this is 30, we don't support
// 4K 60 FPS.
String fpsStr = getXmlString(serverInfo, "RefreshRate");
if (fpsStr == null) {
return false;
}
try {
if (Integer.parseInt(fpsStr) >= 60) {
// 4K supported and 60 FPS is the first entry
return true;
}
} catch (NumberFormatException ignored) {}
return false;
}
public int getCurrentGame(String serverInfo) throws IOException, XmlPullParserException { public int getCurrentGame(String serverInfo) throws IOException, XmlPullParserException {
// GFE 2.8 started keeping currentgame set to the last game played. As a result, it no longer // GFE 2.8 started keeping currentgame set to the last game played. As a result, it no longer
@ -548,16 +572,35 @@ public class NvHTTP {
} }
public int getServerMajorVersion(String serverInfo) throws XmlPullParserException, IOException { public int getServerMajorVersion(String serverInfo) throws XmlPullParserException, IOException {
int[] appVersionQuad = getServerAppVersionQuad(serverInfo);
if (appVersionQuad != null) {
return appVersionQuad[0];
}
else {
return 0;
}
}
public int[] getServerAppVersionQuad(String serverInfo) throws XmlPullParserException, IOException {
try { try {
String serverVersion = getServerVersion(serverInfo); String serverVersion = getServerVersion(serverInfo);
if (serverVersion == null || serverVersion.indexOf('.') < 0) { if (serverVersion == null) {
LimeLog.warning("Malformed server version field"); LimeLog.warning("Missing server version field");
return 0; return null;
} }
return Integer.parseInt(serverVersion.substring(0, serverVersion.indexOf('.'))); String[] serverVersionSplit = serverVersion.split("\\.");
if (serverVersionSplit.length != 4) {
LimeLog.warning("Malformed server version field");
return null;
}
int[] ret = new int[serverVersionSplit.length];
for (int i = 0; i < ret.length; i++) {
ret[i] = Integer.parseInt(serverVersionSplit[i]);
}
return ret;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
e.printStackTrace(); e.printStackTrace();
return 0; return null;
} }
} }