diff --git a/src/com/limelight/nvstream/NvConnection.java b/src/com/limelight/nvstream/NvConnection.java index c57cf72e..4e1b94f8 100644 --- a/src/com/limelight/nvstream/NvConnection.java +++ b/src/com/limelight/nvstream/NvConnection.java @@ -137,13 +137,12 @@ public class NvConnection { try { startSteamBigPicture(); performHandshake(); - videoStream.setupVideoStream(host, video); + videoStream.startVideoStream(host, video); audioStream.startAudioStream(host); beginControlStream(); controlStream.startJitterPackets(); startController(); activity.hideSystemUi(); - videoStream.startVideoStream(host); } catch (XmlPullParserException e) { e.printStackTrace(); displayToast(e.getMessage()); diff --git a/src/com/limelight/nvstream/NvVideoStream.java b/src/com/limelight/nvstream/NvVideoStream.java index 91b895a8..23812a1f 100644 --- a/src/com/limelight/nvstream/NvVideoStream.java +++ b/src/com/limelight/nvstream/NvVideoStream.java @@ -143,19 +143,8 @@ public class NvVideoStream { decrend.setup(1280, 720, renderTarget); } - - public void startVideoStream(final String host) - { - // Read the first frame to start the UDP video stream - try { - readFirstFrame(host); - } catch (IOException e2) { - abort(); - return; - } - } - public void setupVideoStream(final String host, final Surface surface) + public void startVideoStream(final String host, final Surface surface) { // This thread becomes the output display thread Thread t = new Thread() { @@ -180,6 +169,17 @@ public class NvVideoStream { // the reference frame startUdpPingThread(); + // Read the first frame to start the UDP video stream + // This MUST be called before the normal UDP receive thread + // starts in order to avoid state corruption caused by two + // threads simultaneously adding input data. + try { + readFirstFrame(host); + } catch (IOException e2) { + abort(); + return; + } + // Start the receive thread early to avoid missing // early packets startReceiveThread();