Mercurial > hg > Members > riono > TreeVNC_ja_comment
changeset 526:fcd833c2e148
Multicast Bloking in ZRLEDecoder
author | riono210 |
---|---|
date | Thu, 02 May 2019 16:18:44 +0900 |
parents | fea7651ca24f |
children | 96e15614a31f |
files | src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEESender.java src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java |
diffstat | 4 files changed, 99 insertions(+), 104 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java Tue Mar 05 19:33:33 2019 +0900 +++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java Thu May 02 16:18:44 2019 +0900 @@ -26,26 +26,39 @@ import com.glavsoft.drawing.Renderer; import com.glavsoft.exceptions.TransportException; +import com.glavsoft.rfb.encoding.EncodingType; import com.glavsoft.transport.Reader; +import jp.ac.u_ryukyu.treevnc.CheckDelay; import jp.ac.u_ryukyu.treevnc.TreeRFBProto; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; + public class ZRLEDecoder extends ZlibDecoder { private static final int MAX_TILE_SIZE = 64; private int[] decodedBitmap; private int[] palette; - @Override + private int deflate_size = 65507; + private ByteBuffer c1; + private FramebufferUpdateRectangle c1rect; + private int c1headerPos; + + @Override public void decode(Reader reader, Renderer renderer, FramebufferUpdateRectangle rect) throws TransportException { int zippedLength = (int) reader.readUInt32(); if (0 == zippedLength) return; int length = rect.width * rect.height * renderer.getBytesPerPixel(); byte[] bytes = unzip(reader, zippedLength, length, rect.getEncodingType()); - decode1(renderer, rect, bytes, zippedLength, null); + decode1(renderer, null, rect, bytes, zippedLength, null); } - public void decode1(Renderer renderer, - FramebufferUpdateRectangle rect, byte[] bytes, int zippedLength, TreeRFBProto rfbProto) throws TransportException { + public void decode1(Renderer renderer, ByteBuffer header, FramebufferUpdateRectangle rect, byte[] bytes, int zippedLength, TreeRFBProto rfbProto) throws TransportException { int offset = zippedLength; int maxX = rect.x + rect.width; int maxY = rect.y + rect.height; @@ -57,6 +70,14 @@ if (null == decodedBitmap) { decodedBitmap = new int[MAX_TILE_SIZE * MAX_TILE_SIZE]; } + + if (rfbProto.multicastBlocking) { + try { + zrleeBlocking(rfbProto, header, bytes, rect); + } catch (DataFormatException e) { + e.printStackTrace(); + } + } for (int tileY = rect.y; tileY < maxY; tileY += MAX_TILE_SIZE) { int tileHeight = Math.min(maxY - tileY, MAX_TILE_SIZE); @@ -86,7 +107,7 @@ offset += decodePacked(bytes, offset, renderer, paletteSize, tileX, tileY, tileWidth, tileHeight); } } - if (rfbProto != null && rfbProto.multicastBlocking) rfbProto.multicastPut(rect, bytes, prevoffset, offset, tileWidth, tileHeight); + if (rfbProto != null && rfbProto.multicastBlocking) multicastPut(rfbProto, rect, bytes, prevoffset, offset, tileX, tileY,tileWidth, tileHeight); prevoffset = offset; } } @@ -175,4 +196,62 @@ return paletteSize * bytesPerCPixel; } + + /** + * Multicast framebufferUpdate to children. + * read FrameBuffferUpdate. If it is ZLE, make it ZLEE which is self contained compressed packet. + * put the packet to the multicastqueue. Then normal rendering engine read the same stream using is.reset(). + * + * @throws TransportException + * @throws UnsupportedEncodingException + */ + + + private void zrleeBlocking(TreeRFBProto rfb, ByteBuffer header, byte[] bytes, FramebufferUpdateRectangle rect) throws TransportException, DataFormatException { + // dump32(inputs); + c1 = rfb.multicastqueue.allocate(deflate_size); + if (rfb.addSerialNum) + c1.putLong(rfb.counter++); + if (rfb.checkDelay) + CheckDelay.checkDelay(c1, rect.x, rect.y, rect.width, rect.height, System.currentTimeMillis(), EncodingType.CHECK_DELAY); + c1headerPos = c1.position(); + c1.put(header); + header.flip(); + c1.putInt(0); + c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0); + return; + } + + public void multicastPut(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, byte[] bytes, int prevoffset, int offset, int tileX, int tileY, int tileW, int tileH) { + int span = offset - prevoffset; + rfb.deflater.setInput(bytes,prevoffset,span); + c1rect.height = tileH; + if (c1.remaining() < span || c1rect.x + c1rect.width + tileW >= rect.x + rect.width ) { + rfb.deflater.deflate(c1, Deflater.FULL_FLUSH); + rfb.deflater.finish(); + c1.flip(); + //System.out.println("multicastPut: " + c1rect + " length: " + (c1.remaining()-c1headerPos-header.limit())); + try { + rfb.writeUpdateRectangleWithHeader(c1, c1headerPos, c1.remaining()-c1headerPos-header.limit()-4, c1rect.x, c1rect.y, c1rect.width + tileW, c1rect.height + tileY); + } catch (InterruptedException e) { + e.printStackTrace(); + } + c1rect.x += c1rect.width; + if (c1rect.x >= rect.x + rect.width) { + c1rect.x = rect.x; + c1rect.y += tileH; + } + c1rect.width = 0; + c1 = rfb.multicastqueue.allocate(deflate_size); + if (rfb.addSerialNum) + c1.putLong(rfb.counter++); + c1headerPos = c1.position(); + c1.put(header); + header.flip(); + c1.putInt(0); + } else { + rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH); + } + c1rect.width += tileW; + } }
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEESender.java Tue Mar 05 19:33:33 2019 +0900 +++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEESender.java Thu May 02 16:18:44 2019 +0900 @@ -1,6 +1,7 @@ package com.glavsoft.rfb.encoding.decoder; import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; import jp.ac.u_ryukyu.treevnc.TreeRFBProto; @@ -33,8 +34,8 @@ // ReadSendData convert ZRLE to ZRLEE // unzipped data in the bytes byte[] bytes = new byte[rect.width * rect.height * renderer.getBytesPerPixel()]; - rfb.readSendData(dataLen, reader, bytes, rect); - decoder.decode1(renderer, rect, bytes, 0, rfb); + ByteBuffer header = rfb.readSendData(dataLen, reader, bytes, rect); + decoder.decode1(renderer, header, rect, bytes, 0, rfb); return; } else { // no reencoding is required
--- a/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java Tue Mar 05 19:33:33 2019 +0900 +++ b/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java Thu May 02 16:18:44 2019 +0900 @@ -258,6 +258,7 @@ logger.finest(rect.toString() + (0 == numberOfRectangles ? "\n---" : "")); if (decoder != null) { try { + System.out.println(rect); decoder.decode(reader, renderer, rect); // TreeVNC processing here if (rfb.getCuiVersion()) continue; repaintController.repaintBitmap(rect);
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java Tue Mar 05 19:33:33 2019 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java Thu May 02 16:18:44 2019 +0900 @@ -38,11 +38,11 @@ public FindRoot findRoot; public int acceptPort = 0; private String myAddress; - private long counter = 0; // packet serial number + public long counter = 0; // packet serial number public ServerSocket servSock; private static final int INFLATE_BUFSIZE = 1024 * 100; - private Inflater inflater = new Inflater(); - private Deflater deflater = new Deflater(); + public Inflater inflater = new Inflater(); + public Deflater deflater = new Deflater(); ViewerInterface viewer; private short id = 0; // my tree node id ( = 0 in root ), -1 means no parent private short sharingId = -1; // VNCServer's id. this is used control visivility @@ -74,11 +74,7 @@ private byte[] originalInitData = null; private boolean childrenMulticast = true; private static int uniqueNodeId = 0; // uniquenodeid in all trees (less than MAX_UNIQUE_NODE_ID) - private int deflate_size = 65507; - private ByteBuffer header; - private ByteBuffer c1; - private FramebufferUpdateRectangle c1rect; - private int c1headerPos; + private boolean stopBroadcast; public boolean multicastBlocking = true; @@ -639,7 +635,7 @@ * @param reader * @throws TransportException */ - public void readSendData(int dataLen, Reader reader, byte[] bytes, FramebufferUpdateRectangle rect) + public ByteBuffer readSendData(int dataLen, Reader reader, byte[] bytes, FramebufferUpdateRectangle rect) throws TransportException { LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>(); int headerLen = rect.getEncodingType() == EncodingType.CHECK_DELAY ? 24 : 16; @@ -657,14 +653,8 @@ if (encoding == EncodingType.ZRLE.getId() || encoding == EncodingType.ZLIB.getId()) { - if (multicastBlocking) { - try { - zrleeBlocking(dataLen, reader, bytes, rect, context.getPixelFormat().bitsPerPixel/8, bufs, header); - } catch (DataFormatException e) { - e.printStackTrace(); - } - return; - } + + if (multicastBlocking) return header; // recompress into ZREE // uncompressed result is remain in bytes ByteBuffer len = multicastqueue.allocate(4); @@ -705,7 +695,7 @@ } catch (DataFormatException e) { throw new TransportException(e); } - return; + return header; } // ZRLEE is already compressed @@ -721,7 +711,7 @@ } multicastqueue.put(bufs); - return; + return header; } // It may be compressed. We can inflate here to avoid repeating clients // decompressing here, @@ -729,86 +719,10 @@ // each client. // But we have do inflation for all input data, so we have to do it // here. + return header; } - /** - * Multicast framebufferUpdate to children. - * read FrameBuffferUpdate. If it is ZLE, make it ZLEE which is self contained compressed packet. - * put the packet to the multicastqueue. Then normal rendering engine read the same stream using is.reset(). - * - * @param dataLen - * @param reader - * @throws TransportException - * @throws UnsupportedEncodingException - */ - - private void zrleeBlocking(int dataLen, Reader reader, byte[] bytes, FramebufferUpdateRectangle rect, int bytePerPixel, LinkedList<ByteBuffer> bufs, ByteBuffer header) throws TransportException, DataFormatException { - ByteBuffer len = multicastqueue.allocate(4); - reader.readBytes(len.array(), 0, 4); - len.limit(4); - ByteBuffer inputData = multicastqueue.allocate(dataLen - 20); - reader.readBytes(inputData.array(), 0, inputData.capacity()); - inputData.limit(dataLen - 20); - LinkedList<ByteBuffer> inputs = new LinkedList<ByteBuffer>(); - inputs.add(inputData); - header.putInt(12, EncodingType.ZRLEE.getId()); // means - // recompress - // every time - // using new Deflecter every time is incompatible with the - // protocol, clients have to be modified. - Deflater nDeflater = deflater; // new Deflater(); - LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>(); - int inflate_size = rect.width * rect.height * bytePerPixel; - - unzip(inflater, inputs, 0, bytes, inflate_size); - this.header = header; - // dump32(inputs); - c1 = multicastqueue.allocate(deflate_size); - if (addSerialNum) - c1.putLong(counter++); - if (checkDelay) - CheckDelay.checkDelay(c1, rect.x, rect.y, rect.width, rect.height, System.currentTimeMillis(), EncodingType.CHECK_DELAY); - c1headerPos = c1.position(); - c1.put(header); - header.flip(); - c1.putInt(0); - c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0); - return; - } - - public void multicastPut(FramebufferUpdateRectangle rect, byte[] bytes, int prevoffset, int offset, int tilex, int tiley) { - int span = offset - prevoffset; - deflater.setInput(bytes,prevoffset,span); - c1rect.height = tiley; - if (c1.remaining() < span || c1rect.x + c1rect.width + tilex >= rect.x + rect.width ) { - deflater.deflate(c1, Deflater.FULL_FLUSH); - deflater.finish(); - c1.flip(); - //System.out.println("multicastPut: " + c1rect + " length: " + (c1.remaining()-c1headerPos-header.limit())); - try { - writeUpdateRectangleWithHeader(c1, c1headerPos, c1.remaining()-c1headerPos-header.limit()-4, c1rect.x, c1rect.y, c1rect.width, c1rect.height); - } catch (InterruptedException e) { - e.printStackTrace(); - } - c1rect.x += c1rect.width; - if (c1rect.x >= rect.x + rect.width) { - c1rect.x = rect.x; - c1rect.y += tiley; - } - c1rect.width = 0; - c1 = multicastqueue.allocate(deflate_size); - if (addSerialNum) - c1.putLong(counter++); - c1headerPos = c1.position(); - c1.put(header); - header.flip(); - c1.putInt(0); - } else { - deflater.deflate(c1, Deflater.SYNC_FLUSH); - } - c1rect.width += tilex; - } /** * make and send frameBufferUpdateRectangle packet @@ -833,7 +747,7 @@ * 16 [int32] datalen if zcompressed * 20 compressedData */ - private void writeUpdateRectangleWithHeader(ByteBuffer c1, int headerPos, int len2, int x, int y, int w, int h) throws InterruptedException { + public void writeUpdateRectangleWithHeader(ByteBuffer c1, int headerPos, int len2, int x, int y, int w, int h) throws InterruptedException { deflater.reset(); c1.putInt(headerPos + 16, len2);