# HG changeset patch # User Shinji KONO # Date 1582253534 -32400 # Node ID 9a2bef3f302047e6554692fda851c0b9d85dc399 # Parent 705fd8d79378d5ab188c10af24c4a9c5b698eb53 blocking fix broadcast mode diff -r 705fd8d79378 -r 9a2bef3f3020 src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java --- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java Thu Feb 20 17:48:24 2020 +0900 +++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java Fri Feb 21 11:52:14 2020 +0900 @@ -38,13 +38,15 @@ public class ZRLEDecoder extends ZlibDecoder { private static final int MAX_TILE_SIZE = 64; + private static final int RECT_HEADER_SIZE = 16; private int[] decodedBitmap; private int[] palette; + private boolean WifiMulticast; class TileLoop { private final boolean blocking; - final int MARGIN = 18000; - final int deflate_size = 60000-MARGIN; + final int MARGIN = 25000; + final int deflate_size = 62000-MARGIN; private ByteBuffer c1; private int width; // phase2 length private FramebufferUpdateRectangle c0rect,c1rect,rect; @@ -79,7 +81,7 @@ public TileLoop(TreeRFBProto rfb, int offset) { prevoffset = prevLineOffset = flushOffset = offset; prevC1Offset = 0; - if (rfb == null || offset < deflate_size + spanGap) { + if (rfb == null || offset < deflate_size + MARGIN) { // packet size fit in broadcast send it all at once blocking = false; } else @@ -120,7 +122,6 @@ c0rect = null; } - int spanGap = 128; /** * Series of tiles compose at most three rectangles. SYNC_FLUSH is necessary on * rectangle boundaries. @@ -210,7 +211,7 @@ flushMuticast(rfb,bytes); return; } - c1.position(c1.position()+16); // header space + c1.position(c1.position()+ RECT_HEADER_SIZE); // header space prevC1Offset = c1.position(); c1rect = new FramebufferUpdateRectangle(rect.x,c1rect.y+tileH,0,0); } @@ -224,11 +225,12 @@ } else { // first phase 1 case c0rect = c1rect; } + c1rect = new FramebufferUpdateRectangle(rect.x, c0rect.y+c0rect.height, 0, 0); if (end) { + c0rect = null; // next will be first phase 1 case flushMuticast(rfb,bytes); return; } - c1rect = new FramebufferUpdateRectangle(rect.x, c0rect.y+c0rect.height, 0, 0); prevLineOffset = offset; } } @@ -236,22 +238,32 @@ public void makeHeaderSpace() { // previous rectangle is finished, make next header space and copy already compressed part - System.arraycopy(c1.array(),prevC1LineOffset,c1.array(),prevC1LineOffset+16,c1.position()-prevC1LineOffset); - c1.position(c1.position()+16); - prevC1Offset = prevC1LineOffset+16; + System.arraycopy(c1.array(),prevC1LineOffset,c1.array(),prevC1LineOffset+ RECT_HEADER_SIZE,c1.position()-prevC1LineOffset); + c1.position(c1.position()+ RECT_HEADER_SIZE); + prevC1Offset = prevC1LineOffset+ RECT_HEADER_SIZE; } + /** + * + * @param extend use MARGIN + * @param what reason of flush (debug purpose) + * @return packet full + * @throws TransportException + */ private boolean flushDeflator(boolean extend,String what) throws TransportException { // System.out.println("flusing "+what+c1); - if (extend) c1.limit(c1.capacity()-16); + if (extend) c1.limit(c1.capacity()- RECT_HEADER_SIZE); deflater.deflate(c1, Deflater.FULL_FLUSH); if (c1.remaining()==0) { if (!extend) { - c1.limit(c1.capacity()-16); + c1.limit(c1.capacity()- RECT_HEADER_SIZE); deflater.deflate(c1, Deflater.FULL_FLUSH); } - if (c1.remaining() == 0) - throw new TransportException("Multicast packet overrun", null); + if (c1.remaining() == 0) { + ByteBuffer tmp = ByteBuffer.allocate(65536); + deflater.deflate(tmp,Deflater.FULL_FLUSH); + throw new TransportException("Multicast packet overrun "+(c1.limit()+tmp.position())+" bytes required", null); + } return true; } return false; @@ -282,11 +294,11 @@ bufs.add(c1); // rfb.getContext().checkFrameBufferRectanble(c1, bytes, flushOffset, prevoffset); flushOffset = prevoffset; - if (rfb.isTreeManager() && rfb.connectionPresenter.isUseMulticast()) { + if (WifiMulticast) { for (ByteBuffer buf : bufs) rfb.getViewer().getRfbBroadcastListener().multicastUpdateRectangle(buf); - } else { - rfb.multicastqueue.put(bufs); + } else if (rfb.multicastBlocking) { + rfb.multicastqueue.put(bufs); // debug purpose } } } @@ -304,7 +316,7 @@ public void multicastDecode(Reader reader, Renderer renderer, FramebufferUpdateRectangle rect, TreeRFBProto rfb) throws TransportException { - ByteBuffer header = ByteBuffer.allocate(16); + ByteBuffer header = ByteBuffer.allocate(16); // FBU header reader.read(header.array()); int zippedLength = (int) reader.readUInt32(); if (0 == zippedLength) return; @@ -320,7 +332,7 @@ int maxX = rect.x + rect.width; int maxY = rect.y + rect.height; byte[] bytes = buf.array(); - boolean WifiMulticast = rfbProto !=null && (rfbProto.multicastBlocking || rfbProto.getViewer().getUseMulticast()); + WifiMulticast = rfbProto !=null && (rfbProto.multicastBlocking ||(rfbProto.isTreeManager()&&rfbProto.getViewer().getUseMulticast())); TileLoop tileloop = new TileLoop(rfbProto, zippedLength); //System.out.println("decode1: "+rect.toString()); diff -r 705fd8d79378 -r 9a2bef3f3020 src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java --- a/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java Thu Feb 20 17:48:24 2020 +0900 +++ b/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java Fri Feb 21 11:52:14 2020 +0900 @@ -277,7 +277,7 @@ repaintController.repaintBitmap(rect); } catch (Exception e) { e.printStackTrace(); - break; + continue; // we have to read all rectangles } } else if (rect.getEncodingType() == EncodingType.RICH_CURSOR) { RichCursorDecoder.getInstance().decode(reader, renderer, rect); @@ -432,7 +432,7 @@ } } - static public boolean multiasting = false; + static public boolean multiasting = true; public void handleMulticastFrameBufferUpdate(ByteBuffer c1) { FramebufferUpdateRectangle rect = new FramebufferUpdateRectangle();