}
}
-// 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)) {
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) {
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);
} else if (checkbox == &customCompressLevel) {
compressLevel.disabled(!customCompressLevel.checked());
} else if (checkbox == &noJpeg) {
- qualityLevel.disabled(!noJpeg.checked());
+ qualityLevel.disabled(autoSelect.checked() || !noJpeg.checked());
}
}
}
-// 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)) {
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
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;