Mercurial > hg > Members > riono > TreeVNC_ja_comment
changeset 528:2956c4a7bfbd
define TileLoop class
author | anatofuz |
---|---|
date | Fri, 03 May 2019 18:16:58 +0900 |
parents | 96e15614a31f |
children | 9de5137e1598 |
files | src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java |
diffstat | 2 files changed, 171 insertions(+), 165 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java Thu May 02 17:54:09 2019 +0900 +++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java Fri May 03 18:16:58 2019 +0900 @@ -35,6 +35,7 @@ import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; +import java.util.LinkedList; import java.util.zip.DataFormatException; import java.util.zip.Deflater; @@ -43,12 +44,171 @@ private int[] decodedBitmap; private int[] palette; - private int deflate_size = 65507; - private ByteBuffer c1; - private FramebufferUpdateRectangle c1rect; - private int c1headerPos; - private int prevLineOffset; - private int prevC1Offset; + class TileLoop { + private int deflate_size = 65507; + private ByteBuffer c1; + private FramebufferUpdateRectangle c1rect; + private int c1headerPos; + private int prevLineOffset; + private int prevC1Offset; + private int prevoffset; + private Deflater deflater; + + /** + * 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(). + * + * Haeder + * messageID ( FrameBuffer Update + * 1 byte padding + * 2 byte numberofrectangle + * 2 - U16 - x-position + * 2 - U16 - y-position + * 2 - U16 - width + * 2 - U16 - height + * 4 - S32 - encoding-type + * 4 byte datalengths + * datalengths databyte + * + * @throws TransportException + * @throws UnsupportedEncodingException + */ + + + private void zrleeBlocking(TreeRFBProto rfb, ByteBuffer header, byte[] bytes, FramebufferUpdateRectangle rect) throws TransportException, DataFormatException { + // dump32(inputs); + deflater = rfb.deflater; + 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; + } + int spanGap = 128; + + /** + * + * @param rfb + * @param last + * @param header + * @param rect + * @param bytes + * @param offset + * @param tileX + * @param tileY + * @param tileW + * @param tileH + */ + public void multicastPut(TreeRFBProto rfb, boolean last, ByteBuffer header, FramebufferUpdateRectangle rect, byte[] bytes, int offset, int tileX, int tileY, int tileW, int tileH) { + int span = offset - prevoffset; + deflater.setInput(bytes,prevoffset,span); + prevoffset = offset; + c1rect.height += tileH; + c1rect.width += tileW; + if (c1rect.x > rect.x) { // phase0 + if (c1.remaining() > span + spanGap && c1rect.width < rect.width) { + deflater.deflate(c1, Deflater.SYNC_FLUSH); + return; + } + flushRectangle(rfb, header, rect, false); + return; + } + if (!last) { // phase1 + if (c1.remaining() > span + spanGap) { + if (c1rect.width >= rect.width) { + prevLineOffset = offset; + prevC1Offset = c1.position(); + } + deflater.deflate(c1, Deflater.SYNC_FLUSH); + } else { // phase2 + c1.position(prevC1Offset); + flushRectangle(rfb, header, rect, false); + deflater.setInput(bytes, prevLineOffset, span); + deflater.deflate(c1, Deflater.SYNC_FLUSH); + flushRectangle(rfb, header,rect, false); + } + return; + } + flushRectangle(rfb, header, rect, true); + } + + /** + * fix rectangle header + * create next rectangle header + * update position paramater + * send muticast pacate if nessesally + * @param rfb + * @param header + * @param rect + + * @param b + */ + private void flushRectangle(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, boolean b) { + flushMuticast(rfb, header, rect); + } + + private void flushMuticast(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect) { + 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 + 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); + } + + /** + * make and send frameBufferUpdateRectangle packet + * @param c1 + * @param headerPos + * @param len2 + * @param x + * @param y + * @param w + * @param 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); + c1.putShort(headerPos + 4, (short) x); + c1.putShort(headerPos + 6, (short) y); + c1.putShort(headerPos + 8, (short) w); + c1.putShort(headerPos + 10, (short) h); + LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>(); + bufs.add(c1); + if (rfb.isTreeManager && rfb.connectionPresenter.isUseMulticast()) { + for (ByteBuffer buf : bufs) + rfb.viewer.getRfbBroadcastListener().multicastUpdateRectangle(buf); + } else { + rfb.multicastqueue.waitput(bufs); + } + } + } @Override public void decode(Reader reader, Renderer renderer, @@ -64,7 +224,8 @@ int offset = zippedLength; int maxX = rect.x + rect.width; int maxY = rect.y + rect.height; - int prevoffset = offset; + + TileLoop tileloop = new TileLoop(); //System.out.println("decode1: "+rect); if (null == palette) { palette = new int [128]; @@ -75,7 +236,7 @@ if (rfbProto.multicastBlocking) { try { - zrleeBlocking(rfbProto, header, bytes, rect); + tileloop.zrleeBlocking(rfbProto, header, bytes, rect); } catch (DataFormatException e) { e.printStackTrace(); } @@ -109,11 +270,10 @@ offset += decodePacked(bytes, offset, renderer, paletteSize, tileX, tileY, tileWidth, tileHeight); } } - if (rfbProto != null && rfbProto.multicastBlocking) multicastPut(rfbProto, false, header, rect, bytes, prevoffset, offset, tileX, tileY,tileWidth, tileHeight); - prevoffset = offset; + if (rfbProto != null && rfbProto.multicastBlocking) tileloop.multicastPut(rfbProto, false, header, rect, bytes, offset, tileX, tileY,tileWidth, tileHeight); } } - if (rfbProto != null && rfbProto.multicastBlocking) multicastPut(rfbProto, false, header, rect, bytes, prevoffset, offset, maxX, maxY, 0, 0); + if (rfbProto != null && rfbProto.multicastBlocking) tileloop.multicastPut(rfbProto, false, header, rect, bytes, offset, maxX, maxY, 0, 0); } private int decodePlainRle(byte[] bytes, int offset, Renderer renderer, @@ -200,120 +360,5 @@ } - /** - * 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(). - * - * Haeder - * messageID ( FrameBuffer Update - * 1 byte padding - * 2 byte numberofrectangle - * 2 - U16 - x-position - * 2 - U16 - y-position - * 2 - U16 - width - * 2 - U16 - height - * 4 - S32 - encoding-type - * 4 byte datalengths - * datalengths databyte - * - * @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; - } - int spanGap = 128; - - public void multicastPut(TreeRFBProto rfb, boolean last, 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 (c1rect.x > 0) { // phase0 - if (c1.remaining() > span + spanGap && c1rect.width + tileW < rect.width) { - rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH); - return; - } - flushRectangle(rfb, header, offset, rect, tileX, tileY, tileW, tileH, false); - return; - } - if (!last) { // phase1 - if (c1.remaining() > span + spanGap) { - if (tileX == tileW) { - prevLineOffset = offset; - prevC1Offset = c1.position(); - } - rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH); - return; - } - if (tileX < tileW) { // phase2 - c1.position(prevC1Offset); - flushRectangle(rfb, header, prevoffset, rect, 0, tileY-tileH, tileW, tileH, false); - rfb.deflater.setInput(bytes, prevLineOffset, span); - rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH); - flushRectangle(rfb, header, prevoffset, rect, 0, tileY-tileH, tileW, tileH, false); - return; - } - return; - } - flushRectangle(rfb, header, prevoffset, rect, 0, tileY-tileH, tileW, tileH, true); - c1rect.width += tileW; - } - - /** - * fix rectangle header - * create next rectangle header - * update position paramater - * send muticast pacate if necessary - * @param rfb - * @param header - * @param prevoffset - * @param rect - * @param i - * @param i1 - * @param tileW - * @param tileH - * @param b - */ - private void flushRectangle(TreeRFBProto rfb, ByteBuffer header, int prevoffset, FramebufferUpdateRectangle rect, int i, int i1, int tileW, int tileH, boolean b) { - flushMuticast(rfb, header, rect, tileY, tileW, tileH); - } - - private void flushMuticast(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, int tileY, int tileW, int tileH) { - 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); - } }
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java Thu May 02 17:54:09 2019 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java Fri May 03 18:16:58 2019 +0900 @@ -724,46 +724,7 @@ - /** - * make and send frameBufferUpdateRectangle packet - * @param c1 - * @param headerPos - * @param len2 - * @param x - * @param y - * @param w - * @param h - * @throws InterruptedException - * - * [8] sequence number (if used ) - * 0 0 FRAMEBUFFEUPDATERRECTANGLE < headerPos - * 1 0 padding - * 2 int16 count of frame - * 4 int16 x - * 6 int16 y - * 8 int16 w - * 10 int16 h - * 12 int32 encoding type - * 16 [int32] datalen if zcompressed - * 20 compressedData - */ - 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); - c1.putShort(headerPos + 4, (short) x); - c1.putShort(headerPos + 6, (short) y); - c1.putShort(headerPos + 8, (short) w); - c1.putShort(headerPos + 10, (short) h); - LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>(); - bufs.add(c1); - if (isTreeManager && connectionPresenter.isUseMulticast()) { - for (ByteBuffer buf : bufs) - viewer.getRfbBroadcastListener().multicastUpdateRectangle(buf); - } else { - multicastqueue.waitput(bufs); - } - } public LinkedList<ByteBuffer> createCheckDelayHeader(LinkedList<ByteBuffer> checkDelay, ByteBuffer header) { int x = (int) header.getShort(4);