It sends a full update of the screen, in high quality JPEG format, after a programmable idle time. This is disabled by default. Quality can be configured and be truly lossless. ---
Hello, as I said earlier this is the series of automatic lossless refresh implementation. The first patch covers the basic algorithm while the second adds lossy region tracking. It implements mathematically lossless as well as JPEG refresh (selectable on command line, quality 0-9 and special value -1 for mathematically lossless as suggested by DRC). I've fully tested those patches and request they be reviewed and applied to TigerVNC. Thanks common/rfb/ServerCore.cxx | 8 ++++++++ common/rfb/ServerCore.h | 3 ++- common/rfb/VNCSConnectionST.cxx | 37 ++++++++++++++++++++++++++++++++++++- common/rfb/VNCSConnectionST.h | 3 +++ unix/xserver/hw/vnc/Xvnc.man | 16 ++++++++++++++++ 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/common/rfb/ServerCore.cxx b/common/rfb/ServerCore.cxx index ae2fd24..f44a9ca 100644 --- a/common/rfb/ServerCore.cxx +++ b/common/rfb/ServerCore.cxx @@ -93,4 +93,12 @@ rfb::BoolParameter rfb::Server::queryConnect ("QueryConnect", "Prompt the local user to accept or reject incoming connections.", false); +rfb::IntParameter rfb::Server::automaticRefreshDelay +("AutomaticRefreshDelay", + "Delay (in milliseconds) of inactivity after which to refresh framebuffer. 0 disables.", + 0); +rfb::IntParameter rfb::Server::automaticRefreshQuality +("AutomaticRefreshQuality", + "JPEG Quality (0-9) for automatic refresh. Special value -1 uses mathematically lossless compression.", + 9); diff --git a/common/rfb/ServerCore.h b/common/rfb/ServerCore.h index e12a8bc..2f93886 100644 --- a/common/rfb/ServerCore.h +++ b/common/rfb/ServerCore.h @@ -38,6 +38,8 @@ namespace rfb { static IntParameter maxIdleTime; static IntParameter clientWaitTimeMillis; static IntParameter compareFB; + static IntParameter automaticRefreshDelay; + static IntParameter automaticRefreshQuality; static BoolParameter protocol3_3; static BoolParameter alwaysShared; static BoolParameter neverShared; @@ -47,7 +49,6 @@ namespace rfb { static BoolParameter acceptCutText; static BoolParameter sendCutText; static BoolParameter queryConnect; - }; }; diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index deec186..2aa9dd1 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -74,7 +74,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s, drawRenderedCursor(false), removeRenderedCursor(false), continuousUpdates(false), updateTimer(this), pointerEventTime(0), - accessRights(AccessDefault), startTime(time(0)) + accessRights(AccessDefault), startTime(time(0)), refreshTimer(this) { setStreams(&sock->inStream(), &sock->outStream()); peerEndpoint.buf = sock->getPeerEndpoint(); @@ -758,6 +758,9 @@ bool VNCSConnectionST::handleTimeout(Timer* t) writeFramebufferUpdate(); else if (t == &congestionTimer) updateCongestion(); + else if (t == &refreshTimer) { + automaticLosslessRefresh(); + } } catch (rdr::Exception& e) { close(e.str()); } @@ -971,6 +974,7 @@ void VNCSConnectionST::writeFramebufferUpdate() // bit if things are congested. if (isCongested()) { updateTimer.start(50); + refreshTimer.stop(); return; } @@ -1070,6 +1074,7 @@ void VNCSConnectionST::writeFramebufferUpdate() } if (!ui.is_empty() || writer()->needFakeUpdate() || drawRenderedCursor) { + refreshTimer.stop(); // Compute the number of rectangles. Tight encoder makes the things more // complicated as compared to the original VNC4. writer()->setupCurrentEncoder(); @@ -1106,6 +1111,9 @@ void VNCSConnectionST::writeFramebufferUpdate() writeRTTPing(); requested.clear(); + + if (rfb::Server::automaticRefreshDelay > 0) + refreshTimer.start(rfb::Server::automaticRefreshDelay); } out: @@ -1234,3 +1242,30 @@ int VNCSConnectionST::getStatus() return 4; } +void VNCSConnectionST::automaticLosslessRefresh(void) +{ + // Automatic lossless refresh using JPEG Q95, 1X chroma sampling + int q = cp.qualityLevel, fq = cp.fineQualityLevel; + JPEG_SUBSAMP subsampling = cp.subsampling; + bool noJpeg = cp.noJpeg; + + if (Server::automaticRefreshQuality == -1) { + cp.noJpeg = true; + cp.qualityLevel = -1; + } else { + cp.qualityLevel = Server::automaticRefreshQuality; + cp.fineQualityLevel = 5 + cp.qualityLevel * 10; + cp.subsampling = SUBSAMP_NONE; + } + + // Update all the screen (TODO: be smarter) + updates.add_changed(Rect(0, 0, cp.width, cp.height)); + writeFramebufferUpdate(); + refreshTimer.stop(); + + // Reset to previous compression settings + cp.qualityLevel = q; + cp.fineQualityLevel = fq; + cp.subsampling = subsampling; + cp.noJpeg = noJpeg; +} diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h index 72dc59c..153409d 100644 --- a/common/rfb/VNCSConnectionST.h +++ b/common/rfb/VNCSConnectionST.h @@ -178,6 +178,8 @@ namespace rfb { void setDesktopName(const char *name); void setSocketTimeouts(); + void automaticLosslessRefresh(void); + network::Socket* sock; CharArray peerEndpoint; @@ -207,6 +209,7 @@ namespace rfb { Region cuRegion; Timer updateTimer; + Timer refreshTimer; std::set<rdr::U32> pressedKeys; diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man index 356925d..fd19fd0 100644 --- a/unix/xserver/hw/vnc/Xvnc.man +++ b/unix/xserver/hw/vnc/Xvnc.man @@ -223,6 +223,22 @@ where is a hexadecimal keysym. For example, to exchange the " and @ symbols you would specify the following: .IP "" 10 RemapKeys=0x22<>0x40 +.IP "" 7 + +.TP +.B \-AutomaticRefreshDelay \fIdelay +Enable automatic lossless refresh and set the delay to +.I delay +milliseconds. If no updates have been sent to the client in the past +.I delay +milliseconds, Xvnc will update the screen with a visually lossless +(JPEG quality 9) compression. Special value 0 disables automatic refresh (and is the default). + +.TP +.B \-AutomaticRefreshQuality \fIquality +Override the quality of the automatic updates. Use 0-9 to select JPEG quality level, +use -1 as a special value to denote mathematically lossless compression. This option has no effect unless +.I \-AutomaticRefreshDelay is also specified. .SH USAGE WITH INETD By configuring the \fBinetd\fP(1) service appropriately, Xvnc can be launched -- 1.7.9.2 ------------------------------------------------------------------------------ Virtualization & Cloud Management Using Capacity Planning Cloud computing makes use of virtualization - but cloud computing also focuses on allowing computing to be delivered as a service. http://www.accelacomm.com/jaw/sfnl/114/51521223/ _______________________________________________ Tigervnc-devel mailing list Tigervnc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-devel