Mercurial > hg > Members > riono > TreeVNC_ja_comment
comparison src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java @ 535:17a2d0ea5c03
fix on ZRLEDecoder
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 08 May 2019 14:08:34 +0900 |
parents | a3d0ba67e8cf |
children | 6620e04f994c |
comparison
equal
deleted
inserted
replaced
534:a3d0ba67e8cf | 535:17a2d0ea5c03 |
---|---|
40 private static final int MAX_TILE_SIZE = 64; | 40 private static final int MAX_TILE_SIZE = 64; |
41 private int[] decodedBitmap; | 41 private int[] decodedBitmap; |
42 private int[] palette; | 42 private int[] palette; |
43 | 43 |
44 class TileLoop { | 44 class TileLoop { |
45 private final boolean blocking; | |
46 private final int half; | |
45 private int deflate_size = 65507; | 47 private int deflate_size = 65507; |
46 private ByteBuffer c1; | 48 private ByteBuffer c1; |
47 private int width; // phase2 length | 49 private int width; // phase2 length |
48 private FramebufferUpdateRectangle c1rect; | 50 private FramebufferUpdateRectangle c1rect; |
49 private int c1headerPos; | 51 private int c1headerPos; |
55 private int ztileInLine; | 57 private int ztileInLine; |
56 private int hwidth; | 58 private int hwidth; |
57 private int hc1width; | 59 private int hc1width; |
58 private int hoffset; | 60 private int hoffset; |
59 private int hc1offset; | 61 private int hc1offset; |
62 private int discard; | |
60 | 63 |
61 /** | 64 /** |
62 * Multicast framebufferUpdate to children. | 65 * Multicast framebufferUpdate to children. |
63 * read FrameBuffferUpdate. If it is ZLE, make it ZLEE which is self contained compressed packet. | 66 * read FrameBuffferUpdate. If it is ZLE, make it ZLEE which is self contained compressed packet. |
64 * put the packet to the multicastqueue. Then normal rendering engine read the same stream using is.reset(). | 67 * put the packet to the multicastqueue. Then normal rendering engine read the same stream using is.reset(). |
79 * @throws UnsupportedEncodingException | 82 * @throws UnsupportedEncodingException |
80 */ | 83 */ |
81 | 84 |
82 public TileLoop(int offset) { | 85 public TileLoop(int offset) { |
83 prevoffset = prevLineOffset = prevC1Offset = offset; | 86 prevoffset = prevLineOffset = prevC1Offset = offset; |
84 } | 87 if (offset < deflate_size+spanGap) { |
85 | 88 // packet size fit in broadcast send it all at once |
86 private void zrleeBlocking(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect) { | 89 blocking = false; |
90 } else | |
91 blocking = true; | |
92 discard = 0; half = 0; | |
93 } | |
94 | |
95 private void zrleeBlocking(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, byte bytes[]) { | |
87 // dump32(inputs); | 96 // dump32(inputs); |
88 deflater = rfb.deflater; | 97 deflater = rfb.deflater; |
89 newMulticastPacket(rfb, rect); | 98 newMulticastPacket(rfb, rect); |
90 c1.put(header.get(0)); | 99 c1.put(header.get(0)); |
91 c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0); | 100 c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0); |
101 if (!blocking) { | |
102 deflater.setInput(bytes,0,prevoffset); | |
103 deflater.deflate(c1); | |
104 flushMuticast(rfb); | |
105 } | |
92 return; | 106 return; |
93 } | 107 } |
94 | 108 |
95 private void newMulticastPacket(TreeRFBProto rfb, FramebufferUpdateRectangle rect) { | 109 private void newMulticastPacket(TreeRFBProto rfb, FramebufferUpdateRectangle rect) { |
96 c1 = rfb.multicastqueue.allocate(deflate_size); | 110 c1 = rfb.multicastqueue.allocate(deflate_size); |
122 * +----+----------+ | 136 * +----+----------+ |
123 * | | | phase 2 | 137 * | | | phase 2 |
124 * +----+ | 138 * +----+ |
125 * | 139 * |
126 * Broadcast packet have to less than 64kbytes | 140 * Broadcast packet have to less than 64kbytes |
127 * A tile 8x8x3 192byte, a packet can contain 340 raw tiles, when these are | 141 * A tile 64x64x3 11288byte, a packet can contain 5 raw tiles, when these are |
128 * compressed 500 to 2000 tiles can be stored. It is impossible to predict the | 142 * compressed 10 to 100 tiles can be stored. It is impossible to predict the |
129 * compression rate. To check the compressed capacity, Deflate.needsInputs() can | 143 * compression rate. To check the compressed capacity, Deflate.needsInputs() can |
130 * be used. If needsInputs() is false on SYNC_FLUSH, smaller input is necessary. | 144 * be used. If needsInputs() is false on SYNC_FLUSH, smaller input is necessary. |
131 * | 145 * |
132 * We'll try 512 tiles before SYNC_FLUSH in a phase, if it fails try 256. | 146 * We'll try 512 tiles before SYNC_FLUSH in a phase, if it fails try flush former 256 tiles. |
133 * If it will failed again, flush the previous line and try again. | 147 * If it will failed again, flush the previous line and do flush 512 tiles in new Packet. |
134 * If 256 tiles are failed in new packet, discard it. | 148 * If it failed again try former 256 tiles flushed, if this failes again dicard the former half. |
149 * The last case cannot happen but former 256 tiles have to be flushed, because the next 256 lines | |
150 * may failed again and restart the from this point. | |
151 * The next packet start with later 256 tiles filled and unflushed. | |
135 * | 152 * |
136 * @param rfb | 153 * @param rfb |
137 * @param last | 154 * @param last |
138 * @param rect | 155 * @param rect |
139 * @param bytes | 156 * @param bytes |
143 */ | 160 */ |
144 | 161 |
145 int MAX_ZTILE = 512; | 162 int MAX_ZTILE = 512; |
146 | 163 |
147 public void multicastPut(TreeRFBProto rfb, boolean last, FramebufferUpdateRectangle rect, byte[] bytes, int offset, int tileW, int tileH) { | 164 public void multicastPut(TreeRFBProto rfb, boolean last, FramebufferUpdateRectangle rect, byte[] bytes, int offset, int tileW, int tileH) { |
165 if (!blocking) return; | |
148 int span = offset - prevoffset; | 166 int span = offset - prevoffset; |
149 deflater.setInput(bytes,prevoffset,span); | 167 deflater.setInput(bytes,prevoffset,span); |
150 prevoffset = offset; | 168 prevoffset = offset; |
151 c1rect.width += tileW; width += tileW; | 169 c1rect.width += tileW; width += tileW; |
152 if (c1rect.x > rect.x) { // phase 0 | 170 if (c1rect.x > rect.x) { // phase 0 |
181 } | 199 } |
182 } | 200 } |
183 } | 201 } |
184 | 202 |
185 private void compressAndCheckFlush(TreeRFBProto rfb, FramebufferUpdateRectangle rect, byte[] bytes, int offset, boolean flush, boolean last) { | 203 private void compressAndCheckFlush(TreeRFBProto rfb, FramebufferUpdateRectangle rect, byte[] bytes, int offset, boolean flush, boolean last) { |
186 if (!flush && ztileInLine++ < MAX_ZTILE) { | 204 ztileInLine++; |
205 if (!flush && ztileInLine < MAX_ZTILE) { | |
187 if (ztileInLine == MAX_ZTILE/2) { | 206 if (ztileInLine == MAX_ZTILE/2) { |
188 hwidth = width; hc1width = c1rect.width; hoffset = offset; hc1offset = c1.position(); | 207 hwidth = width; hc1width = c1rect.width; hoffset = offset; hc1offset = c1.position(); |
189 } | 208 } |
190 deflater.deflate(c1, Deflater.NO_FLUSH); | 209 deflater.deflate(c1, Deflater.NO_FLUSH); |
191 } else { | 210 } else { |
218 from = prevC1Offset; | 237 from = prevC1Offset; |
219 len = hoffset - prevLineOffset; | 238 len = hoffset - prevLineOffset; |
220 deflater.setInput(bytes, from, len); | 239 deflater.setInput(bytes, from, len); |
221 deflater.deflate(c1, Deflater.SYNC_FLUSH); | 240 deflater.deflate(c1, Deflater.SYNC_FLUSH); |
222 if (!deflater.needsInput()) { /* fatal error discard this line */ | 241 if (!deflater.needsInput()) { /* fatal error discard this line */ |
242 discard++; | |
223 if (!last) { | 243 if (!last) { |
224 newMulticastPacket(rfb, rect); | 244 newMulticastPacket(rfb, rect); |
225 nextRectangle(rect); | 245 nextRectangle(rect); |
226 } | 246 } |
227 return; | 247 return; |
335 if (null == decodedBitmap) { | 355 if (null == decodedBitmap) { |
336 decodedBitmap = new int[MAX_TILE_SIZE * MAX_TILE_SIZE]; | 356 decodedBitmap = new int[MAX_TILE_SIZE * MAX_TILE_SIZE]; |
337 } | 357 } |
338 | 358 |
339 if (rfbProto.multicastBlocking) { | 359 if (rfbProto.multicastBlocking) { |
340 tileloop.zrleeBlocking(rfbProto, header, rect); | 360 tileloop.zrleeBlocking(rfbProto, header, rect,bytes); |
341 } | 361 } |
342 for (int tileY = rect.y; tileY < maxY; tileY += MAX_TILE_SIZE) { | 362 for (int tileY = rect.y; tileY < maxY; tileY += MAX_TILE_SIZE) { |
343 int tileHeight = Math.min(maxY - tileY, MAX_TILE_SIZE); | 363 int tileHeight = Math.min(maxY - tileY, MAX_TILE_SIZE); |
344 | 364 |
345 for (int tileX = rect.x; tileX < maxX; tileX += MAX_TILE_SIZE) { | 365 for (int tileX = rect.x; tileX < maxX; tileX += MAX_TILE_SIZE) { |