@zappar/zappar-cv 0.4.0-beta.1 → 0.4.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -34
- package/README.md +2 -2
- package/lib/additional.d.ts +2 -1
- package/lib/camera-source-map.d.ts +10 -0
- package/lib/camera-source-map.js +40 -0
- package/lib/camera-source.d.ts +2 -5
- package/lib/camera-source.js +3 -13
- package/lib/compatibility.js +1 -1
- package/lib/drawcamera.js +2 -1
- package/lib/gen/zappar-client.js +6 -16
- package/lib/gen/zappar-cwrap.js +37 -28
- package/lib/gen/zappar-native.d.ts +11 -1
- package/lib/gen/zappar-native.js +13 -1
- package/lib/gen/zappar-server.js +1 -5
- package/lib/gen/zappar.d.ts +12 -0
- package/lib/gen/zappar.js +5 -3
- package/lib/gfx.d.ts +1 -0
- package/lib/gfx.js +4 -0
- package/lib/gl-state-manager.d.ts +9 -0
- package/lib/gl-state-manager.js +35 -0
- package/lib/html-element-source.d.ts +3 -20
- package/lib/html-element-source.js +19 -263
- package/lib/image-process-gl.d.ts +37 -0
- package/lib/image-process-gl.js +298 -0
- package/lib/imagebitmap-camera-source.d.ts +36 -0
- package/lib/imagebitmap-camera-source.js +277 -0
- package/lib/imagetracker.d.ts +28 -0
- package/lib/imagetracker.js +119 -0
- package/lib/index.d.ts +1 -1
- package/lib/mstp-camera-source.d.ts +29 -0
- package/lib/mstp-camera-source.js +230 -0
- package/lib/native.js +119 -8
- package/lib/pipeline.d.ts +13 -3
- package/lib/pipeline.js +95 -26
- package/lib/profile.d.ts +2 -0
- package/lib/profile.js +55 -44
- package/lib/riff-reader.d.ts +18 -0
- package/lib/riff-reader.js +56 -0
- package/lib/sequencerecorder.d.ts +1 -0
- package/lib/sequencerecorder.js +11 -0
- package/lib/sequencesource.d.ts +7 -1
- package/lib/sequencesource.js +89 -47
- package/lib/source.d.ts +6 -4
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/worker-client.js +0 -5
- package/lib/worker-imagebitmap.d.ts +5 -0
- package/lib/worker-imagebitmap.js +63 -0
- package/lib/worker-server.d.ts +0 -5
- package/lib/worker-server.js +120 -30
- package/lib/workerinterface.d.ts +47 -1
- package/lib/zcv.js +117 -135
- package/lib/zcv.wasm +0 -0
- package/package.json +34 -31
- package/umd/e9486c1cdadb21608a4f7e2fa3be9517.wasm +0 -0
- package/umd/zappar-cv.js +1 -9
- package/umd/zappar-cv.worker.js +1 -1
- package/lib/bundleworker-mainthread.d.ts +0 -2
- package/lib/bundleworker-mainthread.js +0 -36
- package/lib/bundleworker-worker.d.ts +0 -3
- package/lib/bundleworker-worker.js +0 -47
- package/umd/5dd5cacd27e6e7da828f.bundleworker.js +0 -1
- package/umd/a20150d17b0290cadaa6cb9911ab9500.wasm +0 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { zappar_cwrap } from "./gen/zappar-native";
|
|
2
|
+
import { zappar_server } from "./gen/zappar-server";
|
|
3
|
+
import { MsgManager } from "./messages";
|
|
4
|
+
import { ImageBitmapC2S } from "./workerinterface";
|
|
5
|
+
export declare function handleImageBitmap(m: ImageBitmapC2S, r: zappar_cwrap, server: zappar_server, mgr: MsgManager): void;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleImageBitmap = void 0;
|
|
4
|
+
const image_process_gl_1 = require("./image-process-gl");
|
|
5
|
+
const profile_1 = require("./profile");
|
|
6
|
+
const gl_matrix_1 = require("gl-matrix");
|
|
7
|
+
let pixels;
|
|
8
|
+
let texture;
|
|
9
|
+
let _imageProcessor;
|
|
10
|
+
let _gl;
|
|
11
|
+
function getImageProcessor() {
|
|
12
|
+
if (!_imageProcessor || !_gl) {
|
|
13
|
+
const canvas = new OffscreenCanvas(1, 1);
|
|
14
|
+
_gl = canvas.getContext("webgl");
|
|
15
|
+
if (!_gl)
|
|
16
|
+
throw new Error("Unable to get offscreen GL context");
|
|
17
|
+
_imageProcessor = new image_process_gl_1.ImageProcessGL(_gl);
|
|
18
|
+
}
|
|
19
|
+
return [_imageProcessor, _gl];
|
|
20
|
+
}
|
|
21
|
+
function handleImageBitmap(m, r, server, mgr) {
|
|
22
|
+
// img: ImageBitmap,
|
|
23
|
+
// rot: number,
|
|
24
|
+
// tokenId: number,
|
|
25
|
+
// r: zappar_cwrap,
|
|
26
|
+
// p: zappar_pipeline_t,
|
|
27
|
+
// userFacing: boolean,
|
|
28
|
+
// server: zappar_server,
|
|
29
|
+
// mgr: MsgManager) {
|
|
30
|
+
const [imageProcessor, gl] = getImageProcessor();
|
|
31
|
+
if (!texture) {
|
|
32
|
+
texture = gl.createTexture();
|
|
33
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
34
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
35
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
36
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
37
|
+
}
|
|
38
|
+
if (!texture)
|
|
39
|
+
return;
|
|
40
|
+
if (!pixels || pixels.byteLength < profile_1.profile.dataWidth * profile_1.profile.dataHeight) {
|
|
41
|
+
console.log("Generating pixel buffer", profile_1.profile.dataWidth * profile_1.profile.dataHeight);
|
|
42
|
+
pixels = new ArrayBuffer(profile_1.profile.dataWidth * profile_1.profile.dataHeight);
|
|
43
|
+
}
|
|
44
|
+
imageProcessor.uploadFrame(texture, m.i, m.r, m.userFacing);
|
|
45
|
+
let info = imageProcessor.readFrame(texture, pixels);
|
|
46
|
+
let msg = {
|
|
47
|
+
t: "imageBitmapS2C",
|
|
48
|
+
dataWidth: info.dataWidth,
|
|
49
|
+
dataHeight: info.dataHeight,
|
|
50
|
+
frame: m.i,
|
|
51
|
+
userFacing: info.userFacing,
|
|
52
|
+
uvTransform: info.uvTransform || gl_matrix_1.mat4.create(),
|
|
53
|
+
tokenId: m.tokenId, p: m.p
|
|
54
|
+
};
|
|
55
|
+
mgr.postOutgoingMessage(msg, [m.i]);
|
|
56
|
+
let pipeline = server._pipeline_by_instance.get(m.p);
|
|
57
|
+
if (pipeline) {
|
|
58
|
+
r.pipeline_camera_frame_submit(pipeline, pixels, info.dataWidth, info.dataHeight, m.tokenId, m.cameraToDevice, m.cameraModel, info.userFacing);
|
|
59
|
+
r.pipeline_frame_update(pipeline);
|
|
60
|
+
server.exploreState();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.handleImageBitmap = handleImageBitmap;
|
package/lib/worker-server.d.ts
CHANGED
package/lib/worker-server.js
CHANGED
|
@@ -14,24 +14,12 @@ const ZNM = require("./zcv");
|
|
|
14
14
|
const zappar_cwrap_1 = require("./gen/zappar-cwrap");
|
|
15
15
|
const zappar_server_1 = require("./gen/zappar-server");
|
|
16
16
|
const messages_1 = require("./messages");
|
|
17
|
+
const gl_matrix_1 = require("gl-matrix");
|
|
18
|
+
const zappar_native_1 = require("./gen/zappar-native");
|
|
19
|
+
const worker_imagebitmap_1 = require("./worker-imagebitmap");
|
|
20
|
+
const profile_1 = require("./profile");
|
|
17
21
|
exports.messageManager = new messages_1.MsgManager();
|
|
18
|
-
|
|
19
|
-
self.addEventListener("message", msg => {
|
|
20
|
-
if (msg && msg.data && msg.data.t === "port") {
|
|
21
|
-
// console.log("Got bundle worker port in zcv worker");
|
|
22
|
-
// bundleWorkerPort = msg.data.port;
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
/// export a function accisible from EM_ASM to post a bundle adjustment request data message
|
|
26
|
-
self.send_ba_request = function (buf) {
|
|
27
|
-
var buf_copy = new ArrayBuffer(buf.byteLength);
|
|
28
|
-
new Uint8Array(buf_copy).set(new Uint8Array(buf));
|
|
29
|
-
// console.log("send_ba_request", bundleWorkerPort);
|
|
30
|
-
// bundleWorkerPort?.postMessage({
|
|
31
|
-
// t: "send_ba_request",
|
|
32
|
-
// buf: buf_copy
|
|
33
|
-
// }, [buf_copy]);
|
|
34
|
-
};
|
|
22
|
+
let latestCameraToScreenRotation = 0;
|
|
35
23
|
function launchWorkerServer(wasmUrl) {
|
|
36
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
37
25
|
let mod = ZNM.default({
|
|
@@ -51,18 +39,6 @@ function launchWorkerServer(wasmUrl) {
|
|
|
51
39
|
}, [ab]);
|
|
52
40
|
});
|
|
53
41
|
exports.messageManager.postOutgoingMessage("loaded", []);
|
|
54
|
-
/// addEventListener doesn't seem to work on ports
|
|
55
|
-
// bundleWorkerPort.onmessage = function (msg) {
|
|
56
|
-
// console.log("Message from bundle worker", msg);
|
|
57
|
-
// // Received message from other worker
|
|
58
|
-
// var a_buf = msg.data.buf;
|
|
59
|
-
// var buf = mod._malloc(a_buf.byteLength);
|
|
60
|
-
// mod.HEAPU8.set(new Uint8Array(a_buf), buf);
|
|
61
|
-
// console.log(mod, r);
|
|
62
|
-
// /// call the exported native function to update the world map
|
|
63
|
-
// mod._ba_response_update(buf, msg.data.buf.byteLength);
|
|
64
|
-
// mod._free(buf);
|
|
65
|
-
// }
|
|
66
42
|
exports.messageManager.onIncomingMessage.bind((msg) => {
|
|
67
43
|
var _a;
|
|
68
44
|
switch (msg.t) {
|
|
@@ -73,7 +49,7 @@ function launchWorkerServer(wasmUrl) {
|
|
|
73
49
|
case "buf":
|
|
74
50
|
(_a = server.serializersByPipelineId.get(msg.p)) === null || _a === void 0 ? void 0 : _a.bufferReturn(msg.d);
|
|
75
51
|
break;
|
|
76
|
-
case "cameraFrameC2S":
|
|
52
|
+
case "cameraFrameC2S": {
|
|
77
53
|
let msgt = msg;
|
|
78
54
|
let pipeline = server._pipeline_by_instance.get(msgt.p);
|
|
79
55
|
let att;
|
|
@@ -92,6 +68,22 @@ function launchWorkerServer(wasmUrl) {
|
|
|
92
68
|
};
|
|
93
69
|
exports.messageManager.postOutgoingMessage(ret, [msgt.d]);
|
|
94
70
|
break;
|
|
71
|
+
}
|
|
72
|
+
case "streamC2S": {
|
|
73
|
+
let msgt = msg;
|
|
74
|
+
consumeStream(mod, r, msgt.s, msgt.p, msgt.userFacing, server, msgt.source);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case "cameraToScreenC2S": {
|
|
78
|
+
let msgt = msg;
|
|
79
|
+
latestCameraToScreenRotation = msgt.r;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case "imageBitmapC2S": {
|
|
83
|
+
let msgt = msg;
|
|
84
|
+
worker_imagebitmap_1.handleImageBitmap(msgt, r, server, exports.messageManager);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
95
87
|
}
|
|
96
88
|
});
|
|
97
89
|
}
|
|
@@ -100,3 +92,101 @@ function launchWorkerServer(wasmUrl) {
|
|
|
100
92
|
}
|
|
101
93
|
exports.launchWorkerServer = launchWorkerServer;
|
|
102
94
|
;
|
|
95
|
+
let streamDataBufferPointer = 0;
|
|
96
|
+
let streamDataBufferLength = 0;
|
|
97
|
+
let tokenId = 1;
|
|
98
|
+
const cameraToDeviceTransform = gl_matrix_1.mat4.create();
|
|
99
|
+
const cameraModel = new Float32Array([300, 300, 160, 120, 0, 0]);
|
|
100
|
+
function consumeStream(mod, r, stream, p, userFacing, server, source) {
|
|
101
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
102
|
+
const reader = yield stream.getReader();
|
|
103
|
+
while (true) {
|
|
104
|
+
let result = yield reader.read();
|
|
105
|
+
if (result.done) {
|
|
106
|
+
console.log("Stream done");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
let frame = result.value;
|
|
110
|
+
let size = frame.allocationSize();
|
|
111
|
+
if (size > streamDataBufferLength) {
|
|
112
|
+
if (streamDataBufferPointer > 0)
|
|
113
|
+
mod._free(streamDataBufferPointer);
|
|
114
|
+
streamDataBufferPointer = mod._malloc(size);
|
|
115
|
+
streamDataBufferLength = size;
|
|
116
|
+
}
|
|
117
|
+
yield frame.copyTo(mod.HEAPU8.subarray(streamDataBufferPointer, streamDataBufferPointer + streamDataBufferLength));
|
|
118
|
+
let token = tokenId;
|
|
119
|
+
tokenId++;
|
|
120
|
+
const width = frame.visibleRect.width;
|
|
121
|
+
const height = frame.visibleRect.height;
|
|
122
|
+
let uvTransform;
|
|
123
|
+
let dataWidth = width;
|
|
124
|
+
let dataHeight = height;
|
|
125
|
+
switch (latestCameraToScreenRotation) {
|
|
126
|
+
case 270:
|
|
127
|
+
uvTransform = new Float32Array([0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1]);
|
|
128
|
+
dataWidth = height;
|
|
129
|
+
dataHeight = width;
|
|
130
|
+
break;
|
|
131
|
+
case 180:
|
|
132
|
+
uvTransform = new Float32Array([-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1]);
|
|
133
|
+
break;
|
|
134
|
+
case 90:
|
|
135
|
+
uvTransform = new Float32Array([0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1]);
|
|
136
|
+
dataWidth = height;
|
|
137
|
+
dataHeight = width;
|
|
138
|
+
break;
|
|
139
|
+
default:
|
|
140
|
+
uvTransform = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
let clone = frame.clone();
|
|
144
|
+
if (userFacing)
|
|
145
|
+
gl_matrix_1.mat4.fromScaling(cameraToDeviceTransform, [-1, 1, -1]);
|
|
146
|
+
else
|
|
147
|
+
gl_matrix_1.mat4.identity(cameraToDeviceTransform);
|
|
148
|
+
let focalLength = 300.0 * profile_1.profile.dataWidth / 320.0;
|
|
149
|
+
cameraModel[0] = focalLength;
|
|
150
|
+
cameraModel[1] = focalLength;
|
|
151
|
+
cameraModel[2] = profile_1.profile.dataWidth * 0.5;
|
|
152
|
+
cameraModel[3] = profile_1.profile.dataHeight * 0.5;
|
|
153
|
+
const ret = {
|
|
154
|
+
token: token,
|
|
155
|
+
d: clone,
|
|
156
|
+
p: p,
|
|
157
|
+
t: "videoFrameS2C",
|
|
158
|
+
userFacing,
|
|
159
|
+
uvTransform,
|
|
160
|
+
w: dataWidth,
|
|
161
|
+
h: dataHeight,
|
|
162
|
+
cameraToDevice: cameraToDeviceTransform,
|
|
163
|
+
cameraModel,
|
|
164
|
+
source
|
|
165
|
+
};
|
|
166
|
+
exports.messageManager.postOutgoingMessage(ret, [ret.d, ret.uvTransform.buffer]);
|
|
167
|
+
const pipeline = server._pipeline_by_instance.get(p);
|
|
168
|
+
if (pipeline) {
|
|
169
|
+
r.pipeline_camera_frame_submit_raw_pointer(pipeline, streamDataBufferPointer, size, framePixelFormatFromFormat(frame.format), width, height, token, cameraToDeviceTransform, latestCameraToScreenRotation, cameraModel, userFacing);
|
|
170
|
+
r.pipeline_frame_update(pipeline);
|
|
171
|
+
server.exploreState();
|
|
172
|
+
}
|
|
173
|
+
frame.close();
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
function framePixelFormatFromFormat(f) {
|
|
178
|
+
switch (f) {
|
|
179
|
+
case "I420": return zappar_native_1.frame_pixel_format_t.FRAME_PIXEL_FORMAT_I420;
|
|
180
|
+
case "I420A": return zappar_native_1.frame_pixel_format_t.FRAME_PIXEL_FORMAT_I420A;
|
|
181
|
+
case "I422": return zappar_native_1.frame_pixel_format_t.FRAME_PIXEL_FORMAT_I422;
|
|
182
|
+
case "I444": return zappar_native_1.frame_pixel_format_t.FRAME_PIXEL_FORMAT_I444;
|
|
183
|
+
case "NV12": return zappar_native_1.frame_pixel_format_t.FRAME_PIXEL_FORMAT_NV12;
|
|
184
|
+
case "RGBA":
|
|
185
|
+
case "RGBX":
|
|
186
|
+
return zappar_native_1.frame_pixel_format_t.FRAME_PIXEL_FORMAT_RGBA;
|
|
187
|
+
case "BGRA":
|
|
188
|
+
case "BGRX":
|
|
189
|
+
return zappar_native_1.frame_pixel_format_t.FRAME_PIXEL_FORMAT_BGRA;
|
|
190
|
+
}
|
|
191
|
+
return zappar_native_1.frame_pixel_format_t.FRAME_PIXEL_FORMAT_Y;
|
|
192
|
+
}
|
package/lib/workerinterface.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="dom-webcodecs" />
|
|
2
|
+
import { zappar_camera_source_t, zappar_pipeline_t } from "./gen/zappar-native";
|
|
2
3
|
export interface CameraFrameC2S {
|
|
3
4
|
t: "cameraFrameC2S";
|
|
4
5
|
d: ArrayBuffer;
|
|
@@ -17,3 +18,48 @@ export interface CameraFrameReturnS2C {
|
|
|
17
18
|
p: zappar_pipeline_t;
|
|
18
19
|
att?: Float32Array;
|
|
19
20
|
}
|
|
21
|
+
export interface VideoFrameS2C {
|
|
22
|
+
t: "videoFrameS2C";
|
|
23
|
+
token: number;
|
|
24
|
+
d: VideoFrame;
|
|
25
|
+
p: zappar_pipeline_t;
|
|
26
|
+
source: zappar_camera_source_t;
|
|
27
|
+
userFacing: boolean;
|
|
28
|
+
uvTransform: Float32Array;
|
|
29
|
+
w: number;
|
|
30
|
+
h: number;
|
|
31
|
+
cameraModel: Float32Array;
|
|
32
|
+
cameraToDevice: Float32Array;
|
|
33
|
+
}
|
|
34
|
+
export interface StreamC2S {
|
|
35
|
+
t: "streamC2S";
|
|
36
|
+
p: zappar_pipeline_t;
|
|
37
|
+
s: ReadableStream<VideoFrame>;
|
|
38
|
+
userFacing: boolean;
|
|
39
|
+
source: zappar_camera_source_t;
|
|
40
|
+
}
|
|
41
|
+
export interface CameraToScreenRotationC2S {
|
|
42
|
+
t: "cameraToScreenC2S";
|
|
43
|
+
p: zappar_pipeline_t;
|
|
44
|
+
r: number;
|
|
45
|
+
}
|
|
46
|
+
export interface ImageBitmapC2S {
|
|
47
|
+
t: "imageBitmapC2S";
|
|
48
|
+
p: zappar_pipeline_t;
|
|
49
|
+
i: ImageBitmap;
|
|
50
|
+
r: number;
|
|
51
|
+
userFacing: boolean;
|
|
52
|
+
tokenId: number;
|
|
53
|
+
cameraModel: Float32Array;
|
|
54
|
+
cameraToDevice: Float32Array;
|
|
55
|
+
}
|
|
56
|
+
export interface ImageBitmapS2C {
|
|
57
|
+
t: "imageBitmapS2C";
|
|
58
|
+
p: zappar_pipeline_t;
|
|
59
|
+
dataWidth: number;
|
|
60
|
+
dataHeight: number;
|
|
61
|
+
uvTransform: Float32Array;
|
|
62
|
+
userFacing: boolean;
|
|
63
|
+
frame: ImageBitmap;
|
|
64
|
+
tokenId: number;
|
|
65
|
+
}
|