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

Reply via email to