Since I developed the original ALR mechanism for TurboVNC, I have a couple of comments/critiques of this, based on the real-world usage of the feature in TurboVNC. The first is that people use TurboVNC's ALR feature in the medical viz industry, where mathematical losslessness is important, so it's important that we have the ability to configure either truly lossless (which I think should be the default) and perceptually lossless transmission. As you know, TurboVNC configures this via. -alrqual and -alrsamp command-line arguments (I think you were the one who proposed that modification, actually.)
The second comment expands on Pierre's comment regarding tracking of lossy regions. TurboVNC's version of the Tight encoder will track any subrectangle that is encoded using JPEG and add it to a region called "lossyRegion". The ALR sends only the subrectangles in lossyRegion and only if lossyRegion is not empty, and lossyRegion is immediately cleared after the ALR is sent. Not all rectangles in the Tight protocol are sent using JPEG encoding, even if JPEG is enabled. Rectangles with low numbers of unique colors are sent using mathematically lossless indexed color encoding. Thus, we don't want to re-send those during an ALR, because -- best case -- we're duplicating effort and -- worse case -- if the ALR is perceptually lossless, we're actually making the image quality of those subrects worse. On 2/27/12 5:31 AM, Arthur Huillet wrote: > It sends a full update of the screen, in high quality JPEG format, after a > programmable idle time. > This is disabled by default. > --- > common/rfb/ServerCore.cxx | 8 ++++++++ > common/rfb/ServerCore.h | 3 ++- > common/rfb/VNCSConnectionST.cxx | 29 ++++++++++++++++++++++++++++- > common/rfb/VNCSConnectionST.h | 3 +++ > 4 files changed, 41 insertions(+), 2 deletions(-) > > diff --git a/common/rfb/ServerCore.cxx b/common/rfb/ServerCore.cxx > index ae2fd24..583648e 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::BoolParameter rfb::Server::automaticLosslessRefresh > +("AutomaticLosslessRefresh", > + "Automatically refresh the framebuffer with lossless compression.", > + false); > +rfb::IntParameter rfb::Server::automaticLosslessRefreshDelay > +("AutomaticLosslessRefreshDelay", > + "Delay (in milliseconds) of inactivity after which to refresh framebuffer.", > + 3000); > > diff --git a/common/rfb/ServerCore.h b/common/rfb/ServerCore.h > index e12a8bc..745cdb5 100644 > --- a/common/rfb/ServerCore.h > +++ b/common/rfb/ServerCore.h > @@ -38,6 +38,7 @@ namespace rfb { > static IntParameter maxIdleTime; > static IntParameter clientWaitTimeMillis; > static IntParameter compareFB; > + static IntParameter automaticLosslessRefreshDelay; > static BoolParameter protocol3_3; > static BoolParameter alwaysShared; > static BoolParameter neverShared; > @@ -47,7 +48,7 @@ namespace rfb { > static BoolParameter acceptCutText; > static BoolParameter sendCutText; > static BoolParameter queryConnect; > - > + static BoolParameter automaticLosslessRefresh; > }; > > }; > diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx > index deec186..ec2e35e 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)), alrTimer(this) > { > setStreams(&sock->inStream(), &sock->outStream()); > peerEndpoint.buf = sock->getPeerEndpoint(); > @@ -758,6 +758,10 @@ bool VNCSConnectionST::handleTimeout(Timer* t) > writeFramebufferUpdate(); > else if (t == &congestionTimer) > updateCongestion(); > + else if (t == &alrTimer) { > + fprintf(stderr, "Doing ALR\n"); > + automaticLosslessRefresh(); > + } > } catch (rdr::Exception& e) { > close(e.str()); > } > @@ -971,6 +975,7 @@ void VNCSConnectionST::writeFramebufferUpdate() > // bit if things are congested. > if (isCongested()) { > updateTimer.start(50); > + alrTimer.stop(); > return; > } > > @@ -1070,6 +1075,7 @@ void VNCSConnectionST::writeFramebufferUpdate() > } > > if (!ui.is_empty() || writer()->needFakeUpdate() || drawRenderedCursor) { > + alrTimer.stop(); > // Compute the number of rectangles. Tight encoder makes the things more > // complicated as compared to the original VNC4. > writer()->setupCurrentEncoder(); > @@ -1108,6 +1114,8 @@ void VNCSConnectionST::writeFramebufferUpdate() > requested.clear(); > } > > + if (rfb::Server::automaticLosslessRefresh) > + alrTimer.start(rfb::Server::automaticLosslessRefreshDelay); > out: > network::TcpSocket::cork(sock->getFd(), false); > } > @@ -1234,3 +1242,22 @@ 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; > + cp.qualityLevel = 9; > + cp.fineQualityLevel = 95; > + cp.subsampling = SUBSAMP_NONE; > + > + // Update all the screen (TODO: be smarter) > + framebufferUpdateRequest(Rect(0, 0, cp.width, cp.height), false); > + writeFramebufferUpdate(); > + alrTimer.stop(); > + > + // Reset to previous compression settings > + cp.qualityLevel = q; > + cp.fineQualityLevel = fq; > + cp.subsampling = subsampling; > +} > diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h > index 72dc59c..9b6b112 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 alrTimer; > > std::set<rdr::U32> pressedKeys; > ------------------------------------------------------------------------------ Try before you buy = See our experts in action! The most comprehensive online learning library for Microsoft developers is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, Metro Style Apps, more. Free future releases when you subscribe now! http://p.sf.net/sfu/learndevnow-dev2 _______________________________________________ Tigervnc-devel mailing list Tigervnc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-devel