diff --git a/moonlight-common/src/com/limelight/nvstream/rtsp/RtspConnection.java b/moonlight-common/src/com/limelight/nvstream/rtsp/RtspConnection.java index f12803d4..afbd8189 100644 --- a/moonlight-common/src/com/limelight/nvstream/rtsp/RtspConnection.java +++ b/moonlight-common/src/com/limelight/nvstream/rtsp/RtspConnection.java @@ -17,8 +17,8 @@ public class RtspConnection { public static final int PORT = 48010; public static final int RTSP_TIMEOUT = 5000; - // SHIELD Update 77 - public static final int CLIENT_VERSION = 9; + // GFE 2.1.1 + public static final int CLIENT_VERSION = 10; private int sequenceNumber = 1; private int sessionId = 0; diff --git a/moonlight-common/src/com/limelight/nvstream/rtsp/SdpGenerator.java b/moonlight-common/src/com/limelight/nvstream/rtsp/SdpGenerator.java index 764c33b2..852ef231 100644 --- a/moonlight-common/src/com/limelight/nvstream/rtsp/SdpGenerator.java +++ b/moonlight-common/src/com/limelight/nvstream/rtsp/SdpGenerator.java @@ -42,7 +42,7 @@ public class SdpGenerator { public static String generateSdpFromConfig(InetAddress host, StreamConfiguration sc) { StringBuilder config = new StringBuilder(); config.append("v=0").append("\r\n"); // SDP Version 0 - config.append("o=android 0 9 IN "); + config.append("o=android 0 "+RtspConnection.CLIENT_VERSION+" IN "); if (host instanceof Inet6Address) { config.append("IPv6 "); } @@ -53,26 +53,7 @@ public class SdpGenerator { config.append("\r\n"); config.append("s=NVIDIA Streaming Client").append("\r\n"); - addSessionAttributeBytes(config, "x-nv-callbacks", new byte[] { - 0x50, 0x51, 0x49, 0x4a, 0x0d, - (byte)0xad, 0x30, 0x4a, (byte)0xf1, (byte)0xbd, 0x30, 0x4a, (byte)0xd5, - (byte)0xac, 0x30, 0x4a, 0x21, (byte)0xbc, 0x30, 0x4a, (byte)0xc1, - (byte)0xbb, 0x30, 0x4a, 0x7d, (byte)0xbb, 0x30, 0x4a, 0x19, - (byte)0xbb, 0x30, 0x4a, 0x00, 0x00, 0x00, 0x00 - }); - addSessionAttributeBytes(config, "x-nv-videoDecoder", new byte[] { - 0x50, 0x51, 0x49, 0x4a, 0x65, (byte)0xad, 0x30, 0x4a, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xd1, (byte)0xac, 0x30, - 0x4a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x4d, (byte)0xad, 0x30, 0x4a - }); - addSessionAttributeBytes(config, "x-nv-audioRenderer", new byte[] { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }); - addSessionAttribute(config, "x-nv-general.serverAddress", host.getHostAddress()); - addSessionAttributeInts(config, "x-nv-general.serverPorts", new int[] { 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, @@ -107,150 +88,30 @@ public class SdpGenerator { 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff }); - addSessionAttribute(config, "x-nv-general.videoSyncAudioDelayAdjust", "10000"); - addSessionAttribute(config, "x-nv-general.startTime", "0"); - addSessionAttributeInt(config, "x-nv-general.featureFlags", 0xffffffff); - addSessionAttribute(config, "x-nv-general.userIdleWarningTimeout", "0"); - addSessionAttribute(config, "x-nv-general.userIdleSessionTimeout", "0"); - addSessionAttribute(config, "x-nv-general.serverCapture", "0"); - addSessionAttribute(config, "x-nv-general.clientCapture", "0"); - addSessionAttribute(config, "x-nv-general.rtpQueueMaxPackets", "16"); - addSessionAttribute(config, "x-nv-general.rtpQueueMaxDurationMs", "40"); - addSessionAttribute(config, "x-nv-general.useRtspClient", "257"); + addSessionAttributeInt(config, "x-nv-general.featureFlags", 0x42774141); addSessionAttribute(config, "x-nv-video[0].clientViewportWd", ""+sc.getWidth()); addSessionAttribute(config, "x-nv-video[0].clientViewportHt", ""+sc.getHeight()); - addSessionAttribute(config, "x-nv-video[0].adapterNumber", "0"); addSessionAttribute(config, "x-nv-video[0].maxFPS", ""+sc.getRefreshRate()); - addSessionAttribute(config, "x-nv-video[0].iFrameOnDemand", "1"); - addSessionAttributeInt(config, "x-nv-video[0].transferProtocol", 1); - if (sc.getHeight() >= 1080 && sc.getRefreshRate() >= 60) { - addSessionAttributeInt(config, "x-nv-video[0].rateControlMode", 4); - addSessionAttribute(config, "x-nv-video[0].averageBitrate", "30"); - addSessionAttribute(config, "x-nv-video[0].peakBitrate", "30"); - } - else { - addSessionAttributeInt(config, "x-nv-video[0].rateControlMode", 5); - addSessionAttribute(config, "x-nv-video[0].averageBitrate", "7"); - addSessionAttribute(config, "x-nv-video[0].peakBitrate", "7"); - } + + addSessionAttributeInt(config, "x-nv-video[1].transferProtocol", 0x41514120); + addSessionAttributeInt(config, "x-nv-video[2].transferProtocol", 0x41514120); - addSessionAttribute(config, "x-nv-video[0].gopLength", "60"); - addSessionAttribute(config, "x-nv-video[0].vbvMultiplier", "100"); - addSessionAttribute(config, "x-nv-video[0].slicesPerFrame", "4"); - addSessionAttribute(config, "x-nv-video[0].numTemporalLayers", "0"); - addSessionAttribute(config, "x-nv-video[0].packetSize", ""+sc.getMaxPacketSize()); - addSessionAttribute(config, "x-nv-video[0].enableSubframeEncoding", "0"); - addSessionAttribute(config, "x-nv-video[0].refPicInvalidation", "1"); - addSessionAttribute(config, "x-nv-video[0].pingBackIntervalMs", "3000"); - addSessionAttribute(config, "x-nv-video[0].pingBackTimeoutMs", "10000"); + addSessionAttributeInt(config, "x-nv-video[0].rateControlMode", 0x42414141); + addSessionAttributeInt(config, "x-nv-video[2].rateControlMode", 0x42514141); + addSessionAttribute(config, "x-nv-video[0].timeoutLengthMs", "7000"); - addSessionAttribute(config, "x-nv-video[0].fullFrameAssembly", "1"); - addSessionAttribute(config, "x-nv-video[0].decodeIncompleteFrames", "0"); - addSessionAttribute(config, "x-nv-video[0].enableIntraRefresh", "0"); - addSessionAttribute(config, "x-nv-video[0].enableLongTermReferences", "0"); - addSessionAttribute(config, "x-nv-video[0].enableFrameRateCtrl", "0"); - addSessionAttribute(config, "x-nv-video[0].rtpDynamicPort", "0"); addSessionAttribute(config, "x-nv-video[0].framesWithInvalidRefThreshold", "0"); - addSessionAttribute(config, "x-nv-video[0].consecutiveFrameLostThreshold", "0"); - addSessionAttribute(config, "x-nv-vqos[0].ts.enable", "0"); - addSessionAttribute(config, "x-nv-vqos[0].ts.averageBitrate", "8"); - addSessionAttribute(config, "x-nv-vqos[0].ts.maximumBitrate", "10"); - addSessionAttribute(config, "x-nv-vqos[0].bw.flags", "819"); // Bit 2 being set causes picture problems (should be 823) + // The low nibble of the high byte should be 0x9 but that causes video issues + addSessionAttribute(config, "x-nv-vqos[0].bw.flags", "7091"); - // Clamp the bitrate from 1Mb to the maximum addSessionAttribute(config, "x-nv-vqos[0].bw.maximumBitrate", ""+sc.getBitrate()); - addSessionAttribute(config, "x-nv-vqos[0].bw.minimumBitrate", "1000"); - - addSessionAttribute(config, "x-nv-vqos[0].bw.statsTime", "50"); - addSessionAttribute(config, "x-nv-vqos[0].bw.zeroLossCount", "3000"); - addSessionAttribute(config, "x-nv-vqos[0].bw.lossThreshold", "2"); - addSessionAttribute(config, "x-nv-vqos[0].bw.owdThreshold", "5000"); - addSessionAttribute(config, "x-nv-vqos[0].bw.owdReference", "500"); - addSessionAttribute(config, "x-nv-vqos[0].bw.lossWaitTime", "75"); - addSessionAttribute(config, "x-nv-vqos[0].bw.rateDropMultiplier", "25"); - addSessionAttribute(config, "x-nv-vqos[0].bw.rateGainMultiplier", "10"); - addSessionAttribute(config, "x-nv-vqos[0].bw.maxFps", "60"); - addSessionAttribute(config, "x-nv-vqos[0].bw.minFps", "30"); - addSessionAttribute(config, "x-nv-vqos[0].bw.fpsThreshold", "3"); - addSessionAttribute(config, "x-nv-vqos[0].bw.jitterThreshold", "1000"); - addSessionAttribute(config, "x-nv-vqos[0].bw.jitterWaitTime", "5000"); - addSessionAttribute(config, "x-nv-vqos[0].bw.noJitterWaitTime", "5000"); - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionEnableBitRatePercentThreshold", "110"); - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionEnableL1Threshold", "10"); - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionEnableL0Threshold", "6"); - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionDisableThreshold", "4"); - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionDisableWaitTime", "20000"); - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionDisableWaitPercent", "100"); - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionLowerBoundRate", "1000"); - if (sc.getHeight() >= 1080) { - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionLowerBoundWidth", "1280"); - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionLowerBoundHeight", "720"); - } - else { - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionLowerBoundWidth", "720"); - addSessionAttribute(config, "x-nv-vqos[0].bw.earlyDetectionLowerBoundHeight", "480"); - } - - addSessionAttribute(config, "x-nv-vqos[0].bw.pf.enableFlags", "3"); - - if (sc.getHeight() >= 1080 && sc.getRefreshRate() >= 60) { - addSessionAttribute(config, "x-nv-vqos[0].bw.pf.lowBitrate30FpsThreshold", "5000"); - addSessionAttribute(config, "x-nv-vqos[0].bw.pf.lowBitrate60FpsThreshold", "5000"); - addSessionAttribute(config, "x-nv-vqos[0].bw.pf.highBitrateThreshold", "7000"); - } - else { - addSessionAttribute(config, "x-nv-vqos[0].bw.pf.lowBitrate30FpsThreshold", "4000"); - addSessionAttribute(config, "x-nv-vqos[0].bw.pf.lowBitrate60FpsThreshold", "5000"); - addSessionAttribute(config, "x-nv-vqos[0].bw.pf.highBitrateThreshold", "6000"); - } - addSessionAttribute(config, "x-nv-vqos[0].bw.pf.bitrateStepSize", "1000"); - addSessionAttribute(config, "x-nv-vqos[0].bn.notifyUpBoundThreshold", "40"); - addSessionAttribute(config, "x-nv-vqos[0].bn.notifyLowBoundThreshold", "25"); - addSessionAttribute(config, "x-nv-vqos[0].bn.notifyWaitTime", "3000"); - addSessionAttribute(config, "x-nv-vqos[0].fec.enable", "1"); - addSessionAttribute(config, "x-nv-vqos[0].fec.numSrcPackets", "50"); - addSessionAttribute(config, "x-nv-vqos[0].fec.numOutPackets", "60"); - - // Since we can only deal with FEC data on a 1 packet frame, - // restrict FEC repair percentage to minimum so we get only 1 - // FEC packet per frame - addSessionAttribute(config, "x-nv-vqos[0].fec.repairPercent", "1"); - - addSessionAttribute(config, "x-nv-vqos[0].pictureRefreshIntervalMs", "0"); addSessionAttribute(config, "x-nv-vqos[0].videoQualityScoreUpdateTime", "5000"); - addSessionAttribute(config, "x-nv-vqos[0].invalidateThreshold", "3"); - addSessionAttribute(config, "x-nv-vqos[0].invalidateSkipPercentage", "10"); addSessionAttribute(config, "x-nv-vqos[0].qosTrafficType", "7"); - addSessionAttribute(config, "x-nv-vqos[0].videoQoSMaxRoundTripLatencyFrames", "12"); - addSessionAttribute(config, "x-nv-vqos[0].videoQoSMaxConsecutiveDrops", "3"); - addSessionAttributeInt(config, "x-nv-vqos[0].profile", 0); - - addSessionAttributeInt(config, "x-nv-aqos.mode", 1); - addSessionAttribute(config, "x-nv-aqos.enableAudioStats", "1"); - addSessionAttribute(config, "x-nv-aqos.audioStatsUpdateIntervalMs", "70"); - addSessionAttribute(config, "x-nv-aqos.enablePacketLossPercentage", "1"); - addSessionAttribute(config, "x-nv-aqos.bitRate", "96000"); - addSessionAttribute(config, "x-nv-aqos.packetDuration", "5"); - addSessionAttribute(config, "x-nv-aqos.packetLossPercentageUpdateIntervalMs", "100"); - addSessionAttribute(config, "x-nv-aqos.qosTrafficType", "4"); - - addSessionAttribute(config, "x-nv-runtime.recordClientStats", "8"); - addSessionAttribute(config, "x-nv-runtime.recordServerStats", "0"); - addSessionAttribute(config, "x-nv-runtime.clientNetworkCapture", "0"); - addSessionAttribute(config, "x-nv-runtime.clientTraceCapture", "0"); - addSessionAttribute(config, "x-nv-runtime.serverNetworkCapture", "0"); - addSessionAttribute(config, "x-nv-runtime.serverTraceCapture", "0"); - - addSessionAttributeInt(config, "x-nv-ri.protocol", 0); - addSessionAttribute(config, "x-nv-ri.sendStatus", "0"); - addSessionAttributeInt(config, "x-nv-ri.securityProtocol", 0); - addSessionAttributeBytes(config, "x-nv-ri.secInfo", new byte[0x20a]); - addSessionAttribute(config, "x-nv-videoFrameDropIntervalNumber", "0"); - addSessionAttribute(config, "x-nv-videoFrameDropContinualNumber", "0"); - + addSessionAttribute(config, "x-nv-aqos.qosTrafficType", "8"); + config.append("t=0 0").append("\r\n"); config.append("m=video 47996 ").append("\r\n");