Mercurial > hg > Papers > 2020 > riono-sigos
changeset 11:c9d0d3e1a82f
add code
author | riono <e165729@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 07 May 2020 19:45:00 +0900 |
parents | d2644d8f7893 |
children | 8364e334853c |
files | Paper/riono-sigos.pdf Paper/riono-sigos.tex Paper/src/decode.java Paper/src/multicastPut.java |
diffstat | 4 files changed, 73 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/Paper/riono-sigos.tex Thu May 07 18:45:22 2020 +0900 +++ b/Paper/riono-sigos.tex Thu May 07 19:45:00 2020 +0900 @@ -262,16 +262,21 @@ \end{table} 次にTileLoopの処理について説明する。 -Code\ref{code:tileloop}はTileLoopの処理を擬似的に抜粋したものである。 +Code \ref{code:tileloop}はTileLoopの処理を大まかに抜粋したものである。 \lstinputlisting[caption=TileLoopの処理関数, label=code:tileloop]{src/decode.java} -図\ref{fig:TileLoopFlow}中1にて、TileLoopの初期化でBlockingと構築するPacketの準備を行う。Loop本体ではZRLEで受け取ったRectangleを1Tile 64x64に分割し、1Tileずつ処理を行う。そして受け取ったZRLEより処理を行うTileのデータを取得し、圧縮段階に入る。 +Code \ref{code:tileloop}8 - 11行目はTileLoopの初期化でBlockingと構築するPacketの準備を行っている。Code \ref{code:tileloop}12行目からのLoopではZRLEで受け取ったRectangleを1Tile 64x64に分割し、1Tileずつ処理を行う。%そして受け取ったZRLEより処理を行うTileのデータを取得し、フェーズの確認と圧縮段階に入る。 TileLoopにはc1Rectと呼ばれるRectangleを持っている。これは読み込んだTile分だけ縦横を拡張していくことによってRectangleの再構成を行なっている。図\ref{fig:TIleLoopFlow}中2の圧縮段階では、読み込んだTileのデータを圧縮用のStreamに格納し、java.util.zip.deflaterを利用して圧縮を行なっている。Packetのサイズは60KBとしているが、一旦の制限として42KBまでを格納可能としている。 +Code \ref{code:tileloop}21行目では処理対象のTileのデータ圧縮とフェーズ確認を行う関数である。Code \ref{code:multicastput}はその関数の処理を大まかに抜粋したものである。 + + +\lstinputlisting[caption=TileLoopの処理関数, label=code:multicastput]{src/multicastPut.java} + java.util.zip.deflaterには下記の3種類の圧縮方法がある。 \begin{itemize}
--- a/Paper/src/decode.java Thu May 07 18:45:22 2020 +0900 +++ b/Paper/src/decode.java Thu May 07 19:45:00 2020 +0900 @@ -18,7 +18,7 @@ int tileWidth = Math.min(maxX - tileX, MAX_TILE_SIZE); offset += decodePacked(bytes, offset, renderer, paletteSize, tileX, tileY, tileWidth, tileHeight); if (WifiMulticast) { - tileloop.multicastPut(rfbProto, false, bytes, offset, tileWidth, tileHeight, tileX, tileY); + tileloop.multicastPut(rfbProto, false, bytes, offset, tileWidth, tileHeight, tileX, tileY); } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Paper/src/multicastPut.java Thu May 07 19:45:00 2020 +0900 @@ -0,0 +1,65 @@ +public void multicastPut(TreeRFBProto rfb, boolean last, byte[] bytes, int offset, int tileW, int tileH, int tileX, int tileY) throws TransportException { + int span = offset - prevoffset; + if (span==0) return; + deflater.setInput(bytes, prevoffset, span); + width += tileW; + c1rect.width += tileW; + do { + deflater.deflate(c1, Deflater.SYNC_FLUSH); + if (!deflater.needsInput()) { + flushDeflator(true," full "); + int bytesRead = (int)deflater.getBytesRead(); + prevoffset = flushOffset+bytesRead; + if (c0rect!=null) { // finish pahse 1 + flushRectangle(c0rect,prevC1LineOffset," full c0rect"); + c0rect = null; + } + flushRectangle(c1rect,c1.position()," full c1rect"); // phase 2 + flushMuticast(rfb, bytes); + } + } while (! deflater.needsInput()); + prevoffset = offset; + if (last) { + flushDeflator(false," last"); + if (c0rect!=null) { + flushRectangle(c0rect,prevC1LineOffset," last c0rect"); + makeHeaderSpace(); + c0rect = null; + } + flushRectangle(c1rect,c1.position()," last c1rect"); + flushMuticast(rfb, bytes); + return; + } + if (c1rect.x > rect.x) { // phase 0 + assert(c0rect==null); + if (width >= rect.width) { // end of phase 0 + boolean end = flushDeflator(false," end of phase 0 "); + width = 0; + flushRectangle(c1rect,c1.position()," end of phase 0"); + c1rect = new FramebufferUpdateRectangle(rect.x,c1rect.y+tileH,0,0); + if (end || c1rect.y >= rect.y+rect.height) { + flushMuticast(rfb,bytes); + return; + } + c1.position(c1.position()+ RECT_HEADER_SIZE); // header space + prevC1Offset = c1.position(); + } + } else { // phase 1 + if (width >= rect.width) { // next line + boolean end = flushDeflator(false, " phoase 1 next line "); + width = 0; + prevC1LineOffset = c1.position(); + if (c0rect!=null) { // extend phase 1 + c0rect.height += tileH; + } else { // first phase 1 case + c0rect = c1rect; + } + c1rect = new FramebufferUpdateRectangle(rect.x, c0rect.y+c0rect.height, 0, 0); + if (end || c1rect.y >= rect.y+rect.height) { + c0rect = null; // next will be first phase 1 case + flushMuticast(rfb,bytes); + return; + } + } + } +}