From c06a4ab76df36b6ad43a506bea9e70391ac60a90 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 5 Mar 2016 19:10:22 -0600 Subject: [PATCH] Implement RTSP over ENet --- moonlight-common/libs/tinyrtsp.jar | Bin 8379 -> 8716 bytes .../nvstream/rtsp/RtspConnection.java | 137 +++++++++++++----- 2 files changed, 100 insertions(+), 37 deletions(-) diff --git a/moonlight-common/libs/tinyrtsp.jar b/moonlight-common/libs/tinyrtsp.jar index e87fa76dc8f06704300ab6a0d2be083933ef5937..a03b682a30c575493d083834faa5671d5b429dc0 100644 GIT binary patch delta 5357 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 delta 5040 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 UCb1&$?;2m`5rmCgo9hq#KlGYheE= ConnectionContext.SERVER_GENERATION_5) { + return transactRtspMessageEnet(m); + } + else { + return transactRtspMessageTcp(m); + } + } + private RtspResponse requestOptions() throws IOException { RtspRequest m = createRtspRequest("OPTIONS", "rtsp://"+hostStr); return transactRtspMessage(m); @@ -138,44 +189,56 @@ public class RtspConnection { public void doRtspHandshake() throws IOException { RtspResponse r; - r = requestOptions(); - if (r.getStatusCode() != 200) { - throw new IOException("RTSP OPTIONS request failed: "+r.getStatusCode()); + // Gen 5+ servers do RTSP over ENet instead of TCP + if (context.serverGeneration >= ConnectionContext.SERVER_GENERATION_5) { + enetConnection = EnetConnection.connect(context.serverAddress.getHostAddress(), PORT, RTSP_TIMEOUT); } - r = requestDescribe(); - if (r.getStatusCode() != 200) { - throw new IOException("RTSP DESCRIBE request failed: "+r.getStatusCode()); - } - - // Process the RTSP DESCRIBE response - processDescribeResponse(r); - - r = setupStream("audio"); - if (r.getStatusCode() != 200) { - throw new IOException("RTSP SETUP request failed: "+r.getStatusCode()); - } - - // Process the RTSP SETUP streamid=audio response - processRtspSetupAudio(r); - - r = setupStream("video"); - if (r.getStatusCode() != 200) { - throw new IOException("RTSP SETUP request failed: "+r.getStatusCode()); - } - - r = sendVideoAnnounce(); - if (r.getStatusCode() != 200) { - throw new IOException("RTSP ANNOUNCE request failed: "+r.getStatusCode()); - } - - r = playStream("video"); - if (r.getStatusCode() != 200) { - throw new IOException("RTSP PLAY request failed: "+r.getStatusCode()); - } - r = playStream("audio"); - if (r.getStatusCode() != 200) { - throw new IOException("RTSP PLAY request failed: "+r.getStatusCode()); + try { + r = requestOptions(); + if (r.getStatusCode() != 200) { + throw new IOException("RTSP OPTIONS request failed: "+r.getStatusCode()); + } + + r = requestDescribe(); + if (r.getStatusCode() != 200) { + throw new IOException("RTSP DESCRIBE request failed: "+r.getStatusCode()); + } + + // Process the RTSP DESCRIBE response + processDescribeResponse(r); + + r = setupStream("audio"); + if (r.getStatusCode() != 200) { + throw new IOException("RTSP SETUP request failed: "+r.getStatusCode()); + } + + // Process the RTSP SETUP streamid=audio response + processRtspSetupAudio(r); + + r = setupStream("video"); + if (r.getStatusCode() != 200) { + throw new IOException("RTSP SETUP request failed: "+r.getStatusCode()); + } + + r = sendVideoAnnounce(); + if (r.getStatusCode() != 200) { + throw new IOException("RTSP ANNOUNCE request failed: "+r.getStatusCode()); + } + + r = playStream("video"); + if (r.getStatusCode() != 200) { + throw new IOException("RTSP PLAY request failed: "+r.getStatusCode()); + } + r = playStream("audio"); + if (r.getStatusCode() != 200) { + throw new IOException("RTSP PLAY request failed: "+r.getStatusCode()); + } + } finally { + if (enetConnection != null) { + enetConnection.close(); + enetConnection = null; + } } } }