diff --git a/.gitignore b/.gitignore
index 872556141..e003016dc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,6 @@ validation-status.json
.idea
firefox_profile/*
tests_output
-*.log
\ No newline at end of file
+*.log
+*~
+\#*#
\ No newline at end of file
diff --git a/src/content/capture/canvas-filter/css/main.css b/src/content/capture/canvas-filter/css/main.css
new file mode 100644
index 000000000..246a06052
--- /dev/null
+++ b/src/content/capture/canvas-filter/css/main.css
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+*
+* Use of this source code is governed by a BSD-style license
+* that can be found in the LICENSE file in the root of the source
+* tree.
+*/
+
+canvas {
+ background-color: #ccc;
+ --width: calc(45%);
+ width: var(--width);
+ height: calc(var(--width) * 0.75);
+ margin: 1em;
+ vertical-align: top;
+}
+
+video {
+ --width: calc(45%);
+ width: var(--width);
+ height: calc(var(--width) * 0.75);
+ margin: 1em;
+ object-fit: cover;
+}
diff --git a/src/content/capture/canvas-filter/index.html b/src/content/capture/canvas-filter/index.html
new file mode 100644
index 000000000..2f2fe9d7f
--- /dev/null
+++ b/src/content/capture/canvas-filter/index.html
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Video to Canvas to video
+
+
+
+
+
+
+
+
+
+
+
+
+
WebRTC samplesStream camera via a canvas to a video element
+
+
+
+
+
+
+
+
+
The camera is captured to a video element, which is mapped onto a
+ canvas, and a red square is added.
+
The canvas is then captured to an ImageData object, and painted
+ onto a second canvas.
+
A stream is captured from the second canvas element using its
+ captureStream() method and set as the srcObject of the video element.
+
+
The inputStream, source,
+ canvasIn, canvasOut,
+ result, and stream variables are in global
+ scope, so you can
+ inspect them from the browser console.
+
+
+
+
+
+
diff --git a/src/content/capture/canvas-filter/js/main.js b/src/content/capture/canvas-filter/js/main.js
new file mode 100644
index 000000000..f639aa0e4
--- /dev/null
+++ b/src/content/capture/canvas-filter/js/main.js
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+*
+* Use of this source code is governed by a BSD-style license
+* that can be found in the LICENSE file in the root of the source
+* tree.
+*/
+
+'use strict';
+
+const source = document.querySelector('#source');
+// TODO(hta): Use OffscreenCanvas for the intermediate canvases.
+const canvasIn = document.querySelector('#canvas-source');
+const canvasOut = document.querySelector('#canvas-result');
+const result = document.querySelector('#result');
+
+const stream = canvasOut.captureStream();
+let inputStream = null;
+let imageData = null;
+
+result.srcObject = stream;
+
+function loop() {
+ if (source.videoWidth > 0 && source.videoHeight > 0) {
+ canvasIn.width = source.videoWidth;
+ canvasIn.height = source.videoHeight;
+ let ctx = canvasIn.getContext('2d');
+ ctx.drawImage(source, 0, 0);
+ // Put a red square into the image, to mark it as "processed".
+ ctx.fillStyle = '#FF0000';
+ ctx.fillRect(10, 10, 80, 80);
+ imageData = ctx.getImageData(0, 0, canvasIn.width, canvasIn.height);
+ // At this point, we have data that can be transferred.
+ // We paint it on the second canvas.
+ canvasOut.width = source.videoWidth;
+ canvasOut.height = source.videoHeight;
+ let outCtx = canvasOut.getContext('2d');
+ outCtx.putImageData(imageData, 0, 0);
+ }
+ window.requestAnimationFrame(loop);
+}
+
+(async () => {
+ inputStream = await navigator.mediaDevices.getUserMedia({video: true});
+ source.srcObject = inputStream;
+ source.play();
+ result.play();
+ window.requestAnimationFrame(loop);
+})();
diff --git a/web_server/server.js b/web_server/server.js
new file mode 100644
index 000000000..a85de6ce9
--- /dev/null
+++ b/web_server/server.js
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree.
+ */
+ /* eslint-env node */
+
+'use strict';
+
+var express = require('express');
+var https = require('https');
+var pem = require('pem');
+
+pem.createCertificate({days: 1, selfSigned: true}, function(err, keys) {
+ var options = {
+ key: keys.serviceKey,
+ cert: keys.certificate
+ };
+
+ var app = express();
+
+ app.use(express.static('../'));
+
+ // Create an HTTPS service.
+ https.createServer(options, app).listen(8080);
+
+ console.log('serving on https://localhost:8080');
+});