]> git.proxmox.com Git - mirror_novnc.git/commitdiff
adds qualityLevel property to RFB class for updating JPEG quality level encoding...
authorAndrey Trebler <at@edrilling.no>
Mon, 10 Feb 2020 11:44:36 +0000 (12:44 +0100)
committerAndrey Trebler <at@edrilling.no>
Fri, 28 Feb 2020 12:14:19 +0000 (13:14 +0100)
core/rfb.js
core/util/polyfill.js
docs/API.md
tests/test.rfb.js

index 536ea25cd4460b5454713201e9647cd717e8ca25..72f279a4ddbe0867cccb26014a4a4050cda08103 100644 (file)
@@ -275,6 +275,8 @@ export default class RFB extends EventTargetMixin {
             Log.Warn("Specifying showDotCursor as a RFB constructor argument is deprecated");
             this._showDotCursor = options.showDotCursor;
         }
+
+        this._qualityLevel = 6;
     }
 
     // ===== PROPERTIES =====
@@ -337,6 +339,26 @@ export default class RFB extends EventTargetMixin {
     get background() { return this._screen.style.background; }
     set background(cssValue) { this._screen.style.background = cssValue; }
 
+    get qualityLevel() {
+        return this._qualityLevel;
+    }
+    set qualityLevel(qualityLevel) {
+        if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) {
+            Log.Error("qualityLevel must be an integer between 0 and 9");
+            return;
+        }
+
+        if (this._qualityLevel === qualityLevel) {
+            return;
+        }
+
+        this._qualityLevel = qualityLevel;
+
+        if (this._rfb_connection_state === 'connected') {
+            this._sendEncodings();
+        }
+    }
+
     // ===== PUBLIC METHODS =====
 
     disconnect() {
@@ -1294,7 +1316,7 @@ export default class RFB extends EventTargetMixin {
         encs.push(encodings.encodingRaw);
 
         // Psuedo-encoding settings
-        encs.push(encodings.pseudoEncodingQualityLevel0 + 6);
+        encs.push(encodings.pseudoEncodingQualityLevel0 + this._qualityLevel);
         encs.push(encodings.pseudoEncodingCompressLevel0 + 2);
 
         encs.push(encodings.pseudoEncodingDesktopSize);
index 648ceebc3c22565db50d4941d0aae1dba7dc7c50..0e458c8606badc5adfc4ac713dcc5029867866bf 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * noVNC: HTML5 VNC client
- * Copyright (C) 2018 The noVNC Authors
+ * Copyright (C) 2020 The noVNC Authors
  * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
  */
 
@@ -52,3 +52,10 @@ if (typeof Object.assign != 'function') {
         window.CustomEvent = CustomEvent;
     }
 })();
+
+/* Number.isInteger() (taken from MDN) */
+Number.isInteger = Number.isInteger || function isInteger(value) {
+    return typeof value === 'number' &&
+      isFinite(value) &&
+      Math.floor(value) === value;
+};
index aa6337fe81aba47cd446aa9fb7a5eac46e6e5906..1b00179e1e312e9aab2bd7a570de4a172142d8e8 100644 (file)
@@ -64,6 +64,11 @@ protocol stream.
     to the element containing the remote session screen. The default value is `rgb(40, 40, 40)`
     (solid gray color).
 
+`qualityLevel`
+  - Is an `int` in range `[0-9]` controlling the desired JPEG quality.
+    Value `0` implies low quality and `9` implies high quality.
+    Default value is `6`.
+
 `capabilities` *Read only*
   - Is an `Object` indicating which optional extensions are available
     on the server. Some methods may only be called if the corresponding
index 41232aee67e26557a0b37799670896c560b1476a..4e2739358390bdd3caba3689553acc0b028c1858 100644 (file)
@@ -2865,6 +2865,108 @@ describe('Remote Frame Buffer Protocol Client', function () {
             // error events do nothing
         });
     });
+
+    describe('Quality level setting', function () {
+        const defaultQuality = 6;
+
+        let client;
+
+        beforeEach(function () {
+            client = make_rfb();
+            sinon.spy(RFB.messages, "clientEncodings");
+        });
+
+        afterEach(function () {
+            RFB.messages.clientEncodings.restore();
+        });
+
+        it(`should equal ${defaultQuality} by default`, function () {
+            expect(client._qualityLevel).to.equal(defaultQuality);
+        });
+
+        it('should ignore non-integers when set', function () {
+            client.qualityLevel = '1';
+            expect(RFB.messages.clientEncodings).to.not.have.been.called;
+
+            RFB.messages.clientEncodings.resetHistory();
+
+            client.qualityLevel = 1.5;
+            expect(RFB.messages.clientEncodings).to.not.have.been.called;
+
+            RFB.messages.clientEncodings.resetHistory();
+
+            client.qualityLevel = null;
+            expect(RFB.messages.clientEncodings).to.not.have.been.called;
+
+            RFB.messages.clientEncodings.resetHistory();
+
+            client.qualityLevel = undefined;
+            expect(RFB.messages.clientEncodings).to.not.have.been.called;
+
+            RFB.messages.clientEncodings.resetHistory();
+
+            client.qualityLevel = {};
+            expect(RFB.messages.clientEncodings).to.not.have.been.called;
+        });
+
+        it('should ignore integers out of range [0, 9]', function () {
+            client.qualityLevel = -1;
+            expect(RFB.messages.clientEncodings).to.not.have.been.called;
+
+            RFB.messages.clientEncodings.resetHistory();
+
+            client.qualityLevel = 10;
+            expect(RFB.messages.clientEncodings).to.not.have.been.called;
+        });
+
+        it('should send clientEncodings with new quality value', function () {
+            let newQuality;
+
+            newQuality = 8;
+            client.qualityLevel = newQuality;
+            expect(client.qualityLevel).to.equal(newQuality);
+            expect(RFB.messages.clientEncodings).to.have.been.calledOnce;
+            expect(RFB.messages.clientEncodings.getCall(0).args[1]).to.include(encodings.pseudoEncodingQualityLevel0 + newQuality);
+        });
+
+        it('should not send clientEncodings if quality is the same', function () {
+            let newQuality;
+
+            newQuality = 2;
+            client.qualityLevel = newQuality;
+            expect(RFB.messages.clientEncodings).to.have.been.calledOnce;
+            expect(RFB.messages.clientEncodings.getCall(0).args[1]).to.include(encodings.pseudoEncodingQualityLevel0 + newQuality);
+
+            RFB.messages.clientEncodings.resetHistory();
+
+            client.qualityLevel = newQuality;
+            expect(RFB.messages.clientEncodings).to.not.have.been.called;
+        });
+
+        it('should not send clientEncodings if not in connected state', function () {
+            let newQuality;
+
+            client._rfb_connection_state = '';
+            newQuality = 2;
+            client.qualityLevel = newQuality;
+            expect(RFB.messages.clientEncodings).to.not.have.been.called;
+
+            RFB.messages.clientEncodings.resetHistory();
+
+            client._rfb_connection_state = 'connnecting';
+            newQuality = 6;
+            client.qualityLevel = newQuality;
+            expect(RFB.messages.clientEncodings).to.not.have.been.called;
+
+            RFB.messages.clientEncodings.resetHistory();
+
+            client._rfb_connection_state = 'connected';
+            newQuality = 5;
+            client.qualityLevel = newQuality;
+            expect(RFB.messages.clientEncodings).to.have.been.calledOnce;
+            expect(RFB.messages.clientEncodings.getCall(0).args[1]).to.include(encodings.pseudoEncodingQualityLevel0 + newQuality);
+        });
+    });
 });
 
 describe('RFB messages', function () {