Skip to content
Snippets Groups Projects
Commit a27d3e8e authored by Reiter, Christoph's avatar Reiter, Christoph :snake:
Browse files

Move the QR detection out of the redraw loop

We now queue it and in the callback check if the scan is still active,
and go from there. This means we redraw all the time and detect mostly
in the background.

This results in worse perf with the old library since that isn't async, but
we can always revert if needed.
parent 93134cd9
No related branches found
No related tags found
No related merge requests found
Pipeline #13669 passed
...@@ -248,13 +248,13 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { ...@@ -248,13 +248,13 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) {
let video = await createVideoElement(this._activeCamera); let video = await createVideoElement(this._activeCamera);
this._askPermission = false; this._askPermission = false;
let lastVideoScanTime = -1;
let lastCode = null; let lastCode = null;
let lastSentData = null; let lastSentData = null;
let detector = new QRScanner(); let detector = new QRScanner();
let detectorRunning = false;
const tick = async () => { const tick = () => {
this._requestID = null; this._requestID = null;
if (video.readyState === video.HAVE_ENOUGH_DATA) { if (video.readyState === video.HAVE_ENOUGH_DATA) {
this._loading = false; this._loading = false;
...@@ -277,18 +277,31 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { ...@@ -277,18 +277,31 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) {
maskStartX = canvasElement.width/2 - maskWidth/2; maskStartX = canvasElement.width/2 - maskWidth/2;
maskStartY = canvasElement.height/2 - maskHeight/2; maskStartY = canvasElement.height/2 - maskHeight/2;
let code = null; let lastVideo = video;
// We only check for QR codes 5 times a second to improve performance if (!detectorRunning) {
let shouldAnalyze = Math.abs(lastVideoScanTime - video.currentTime) >= 1/3; detectorRunning = true;
if (shouldAnalyze) { detector.scan(canvasElement, maskStartX, maskStartY, maskWidth, maskHeight).then((code) => {
lastVideoScanTime = video.currentTime; detectorRunning = false;
code = await detector.scan(canvasElement, maskStartX, maskStartY, maskWidth, maskHeight); // if we got restarted then the video element is new, so stop then.
lastCode = code; if (lastVideo !== this._videoElement)
} else { return;
code = lastCode; lastCode = code;
if (code) {
if (lastSentData !== code.data) {
this._outputData = code.data;
this.dispatchEvent(new CustomEvent("code-detected",
{bubbles: true, composed: true, detail: {'code': code.data}}));
}
lastSentData = code.data;
} else {
this._outputData = null;
lastSentData = null;
}
});
} }
let matched = code ? code.data.match(this.matchRegex) !== null : false; let matched = lastCode ? lastCode.data.match(this.matchRegex) !== null : false;
//draw mask //draw mask
canvas.beginPath(); canvas.beginPath();
...@@ -301,7 +314,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { ...@@ -301,7 +314,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) {
canvas.fill(); canvas.fill();
canvas.beginPath(); canvas.beginPath();
if (code) { if (lastCode) {
let okColor = getComputedStyle(this).getPropertyValue('--dbp-success-bg-color'); let okColor = getComputedStyle(this).getPropertyValue('--dbp-success-bg-color');
let notOkColor = getComputedStyle(this).getPropertyValue('--dbp-danger-bg-color'); let notOkColor = getComputedStyle(this).getPropertyValue('--dbp-danger-bg-color');
canvas.fillStyle = matched ? okColor : notOkColor; canvas.fillStyle = matched ? okColor : notOkColor;
...@@ -329,18 +342,6 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { ...@@ -329,18 +342,6 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) {
this.dispatchEvent(new CustomEvent("scan-started", {bubbles: true, composed: true})); this.dispatchEvent(new CustomEvent("scan-started", {bubbles: true, composed: true}));
firstDrawDone = true; firstDrawDone = true;
} }
if (code) {
if (lastSentData !== code.data) {
this._outputData = code.data;
this.dispatchEvent(new CustomEvent("code-detected",
{bubbles: true, composed: true, detail: {'code': code.data}}));
}
lastSentData = code.data;
} else {
this._outputData = null;
lastSentData = null;
}
} }
console.assert(this._requestID === null); console.assert(this._requestID === null);
this._requestID = requestAnimationFrame(tick); this._requestID = requestAnimationFrame(tick);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment