From: Pierre Ossman Date: Thu, 12 Mar 2009 12:25:11 +0000 (+0000) Subject: Improve auto mode for new JPEG code. X-Git-Tag: v0.0.90~127 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=78b2359dcad4bc07ffee55353eca14092e2fba8c;p=tigervnc.git Improve auto mode for new JPEG code. Change auto mode to always select Tight encoding and tweak the quality level based on bandwidth instead of the previous method of changing encoding. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3662 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- diff --git a/unix/vncviewer/CConn.cxx b/unix/vncviewer/CConn.cxx index 53d5ed3d..db364895 100644 --- a/unix/vncviewer/CConn.cxx +++ b/unix/vncviewer/CConn.cxx @@ -670,39 +670,51 @@ void CConn::reconfigureViewport() } } -// Note: The method below is duplicated in vncviewer/cview.cxx! +// Note: The method below is duplicated in win/vncviewer/CConn.cxx! // autoSelectFormatAndEncoding() chooses the format and encoding appropriate // to the connection speed: // -// Above 16Mbps (timing for at least a second), switch to hextile -// Otherwise, switch to ZRLE +// First we wait for at least one second of bandwidth measurement. // -// Above 256Kbps, use full colour mode +// Above 16Mbps (i.e. LAN), we choose the second highest JPEG quality, +// which should be perceptually lossless. +// +// If the bandwidth is below that, we choose a more lossy JPEG quality. +// +// If the bandwidth drops below 256 Kbps, we switch to palette mode. +// +// Note: The system here is fairly arbitrary and should be replaced +// with something more intelligent at the server end. // void CConn::autoSelectFormatAndEncoding() { int kbitsPerSecond = sock->inStream().kbitsPerSecond(); - unsigned int newEncoding = currentEncoding; - bool newFullColour = fullColour; unsigned int timeWaited = sock->inStream().timeWaited(); + bool newFullColour = fullColour; + int newQualityLevel = qualityLevel; - // Select best encoding - if (kbitsPerSecond > 16000 && timeWaited >= 10000) { - newEncoding = encodingHextile; - } else { - newEncoding = encodingZRLE; - } - - if (newEncoding != currentEncoding) { - vlog.info("Throughput %d kbit/s - changing to %s encoding", - kbitsPerSecond, encodingName(newEncoding)); - currentEncoding = newEncoding; - encodingChange = true; - } + // Always use Tight + currentEncoding = encodingTight; - if (kbitsPerSecond == 0) { + // Check that we have a decent bandwidth measurement + if ((kbitsPerSecond == 0) || (timeWaited < 10000)) return; + + // Select appropriate quality level + if (!noJpeg) { + if (kbitsPerSecond > 16000) + newQualityLevel = 8; + else + newQualityLevel = 6; + + if (newQualityLevel != qualityLevel) { + vlog.info("Throughput %d kbit/s - changing to quality %d ", + kbitsPerSecond, newQualityLevel); + cp.qualityLevel = newQualityLevel; + qualityLevel.setParam(newQualityLevel); + encodingChange = true; + } } if (cp.beforeVersion(3, 8)) { diff --git a/unix/vncviewer/OptionsDialog.h b/unix/vncviewer/OptionsDialog.h index 68ce8d6a..44b662c5 100644 --- a/unix/vncviewer/OptionsDialog.h +++ b/unix/vncviewer/OptionsDialog.h @@ -145,7 +145,7 @@ public: sendPrimary.disabled(!sendClipboard.checked()); dotWhenNoCursor.disabled(!useLocalCursor.checked()); compressLevel.disabled(!customCompressLevel.checked()); - qualityLevel.disabled(!noJpeg.checked()); + qualityLevel.disabled(autoSelect.checked() || !noJpeg.checked()); } virtual void takeFocus(Time time) { @@ -171,6 +171,7 @@ public: mediumColour.disabled(autoSelect.checked()); lowColour.disabled(autoSelect.checked()); veryLowColour.disabled(autoSelect.checked()); + qualityLevel.disabled(autoSelect.checked() || !noJpeg.checked()); } else if (checkbox == &fullColour || checkbox == &mediumColour || checkbox == &lowColour || checkbox == &veryLowColour) { fullColour.checked(checkbox == &fullColour); @@ -189,7 +190,7 @@ public: } else if (checkbox == &customCompressLevel) { compressLevel.disabled(!customCompressLevel.checked()); } else if (checkbox == &noJpeg) { - qualityLevel.disabled(!noJpeg.checked()); + qualityLevel.disabled(autoSelect.checked() || !noJpeg.checked()); } } diff --git a/win/vncviewer/CConn.cxx b/win/vncviewer/CConn.cxx index 81df866b..874db094 100644 --- a/win/vncviewer/CConn.cxx +++ b/win/vncviewer/CConn.cxx @@ -514,40 +514,51 @@ CConn::framebufferUpdateEnd() { } -// Note: The method below is duplicated in vncviewer_unix/CConn.cxx! +// Note: The method below is duplicated in win/vncviewer/CConn.cxx! // autoSelectFormatAndEncoding() chooses the format and encoding appropriate // to the connection speed: // -// Above 16Mbps (timing for at least a second), switch to hextile -// Otherwise, switch to ZRLE +// First we wait for at least one second of bandwidth measurement. // -// Above 256Kbps, use full colour mode +// Above 16Mbps (i.e. LAN), we choose the second highest JPEG quality, +// which should be perceptually lossless. // -void -CConn::autoSelectFormatAndEncoding() { +// If the bandwidth is below that, we choose a more lossy JPEG quality. +// +// If the bandwidth drops below 256 Kbps, we switch to palette mode. +// +// Note: The system here is fairly arbitrary and should be replaced +// with something more intelligent at the server end. +// +void CConn::autoSelectFormatAndEncoding() +{ int kbitsPerSecond = sock->inStream().kbitsPerSecond(); - unsigned int newEncoding = options.preferredEncoding; - - bool newFullColour = options.fullColour; unsigned int timeWaited = sock->inStream().timeWaited(); + bool newFullColour = options.fullColour; + int newQualityLevel = options.qualityLevel; - // Select best encoding - if (kbitsPerSecond > 16000 && timeWaited >= 10000) { - newEncoding = encodingHextile; - } else { - newEncoding = encodingZRLE; - } - - if (newEncoding != options.preferredEncoding) { - vlog.info("Throughput %d kbit/s - changing to %s encoding", - kbitsPerSecond, encodingName(newEncoding)); - options.preferredEncoding = newEncoding; - encodingChange = true; - } + // Always use Tight + options.preferredEncoding = encodingTight; - if (kbitsPerSecond == 0) { + // Check that we have a decent bandwidth measurement + if ((kbitsPerSecond == 0) || (timeWaited < 10000)) return; + + // Select appropriate quality level + if (!options.noJpeg) { + if (kbitsPerSecond > 16000) + newQualityLevel = 8; + else + newQualityLevel = 6; + + if (newQualityLevel != options.qualityLevel) { + vlog.info("Throughput %d kbit/s - changing to quality %d ", + kbitsPerSecond, newQualityLevel); + cp.qualityLevel = newQualityLevel; + options.qualityLevel = newQualityLevel; + encodingChange = true; + } } if (cp.beforeVersion(3, 8)) { @@ -565,11 +576,11 @@ CConn::autoSelectFormatAndEncoding() { newFullColour = (kbitsPerSecond > 256); if (newFullColour != options.fullColour) { vlog.info("Throughput %d kbit/s - full color is now %s", - kbitsPerSecond, - newFullColour ? "enabled" : "disabled"); + kbitsPerSecond, + newFullColour ? "enabled" : "disabled"); options.fullColour = newFullColour; formatChange = true; - } + } } void diff --git a/win/vncviewer/OptionsDialog.cxx b/win/vncviewer/OptionsDialog.cxx index 545522e7..f8562510 100644 --- a/win/vncviewer/OptionsDialog.cxx +++ b/win/vncviewer/OptionsDialog.cxx @@ -121,24 +121,27 @@ public: return true; } virtual bool onCommand(int id, int cmd) { + bool aut = isItemChecked(IDC_ENCODING_AUTO); + bool jpeg = isItemChecked(IDC_ALLOW_JPEG); + bool custom_comp = isItemChecked(IDC_CUSTOM_COMPRESSLEVEL); if (id == IDC_ENCODING_AUTO) { - bool ok = !isItemChecked(IDC_ENCODING_AUTO); - enableItem(IDC_ENCODING_TIGHT, ok); - enableItem(IDC_ENCODING_ZRLE, ok); - enableItem(IDC_ENCODING_HEXTILE, ok); - enableItem(IDC_ENCODING_RAW, ok); - enableItem(IDC_FORMAT_FULLCOLOUR, ok); - enableItem(IDC_FORMAT_MEDIUMCOLOUR, ok); - enableItem(IDC_FORMAT_LOWCOLOUR, ok); - enableItem(IDC_FORMAT_VERYLOWCOLOUR, ok); + enableItem(IDC_ENCODING_TIGHT, !aut); + enableItem(IDC_ENCODING_ZRLE, !aut); + enableItem(IDC_ENCODING_HEXTILE, !aut); + enableItem(IDC_ENCODING_RAW, !aut); + enableItem(IDC_FORMAT_FULLCOLOUR, !aut); + enableItem(IDC_FORMAT_MEDIUMCOLOUR, !aut); + enableItem(IDC_FORMAT_LOWCOLOUR, !aut); + enableItem(IDC_FORMAT_VERYLOWCOLOUR, !aut); + enableItem(IDC_QUALITYLEVEL, !aut && jpeg); return true; } if (id == IDC_CUSTOM_COMPRESSLEVEL) { - enableItem(IDC_COMPRESSLEVEL, isItemChecked(IDC_CUSTOM_COMPRESSLEVEL)); + enableItem(IDC_COMPRESSLEVEL, custom_comp); return true; } if (id == IDC_ALLOW_JPEG) { - enableItem(IDC_QUALITYLEVEL, isItemChecked(IDC_ALLOW_JPEG)); + enableItem(IDC_QUALITYLEVEL, !aut && jpeg); return true; } return false;