@zappar/zappar-cv 3.2.0-beta.3 → 3.3.0-beta.1

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/README.md CHANGED
@@ -18,8 +18,8 @@ npm i @zappar/zappar-cv
18
18
 
19
19
  You can use our CDN from within your HTML:
20
20
  ```
21
- <script src="https://libs.zappar.com/zappar-cv/3.2.0-beta.3/zappar-cv.js"></script>
21
+ <script src="https://libs.zappar.com/zappar-cv/3.3.0-beta.1/zappar-cv.js"></script>
22
22
  ```
23
23
 
24
24
  Or you can download and host our standalone JavaScript bundle:
25
- [https://libs.zappar.com/zappar-cv/3.2.0-beta.3/zappar-cv.zip](https://libs.zappar.com/zappar-cv/3.2.0-beta.3/zappar-cv.zip)
25
+ [https://libs.zappar.com/zappar-cv/3.3.0-beta.1/zappar-cv.zip](https://libs.zappar.com/zappar-cv/3.3.0-beta.1/zappar-cv.zip)
@@ -1,4 +1,4 @@
1
- import { CameraFrameData } from "./camera-frame-data";
1
+ import { CameraFrameData, CameraFrameDataRGB } from "./camera-frame-data";
2
2
  import { zappar_face_mesh_t, zappar_face_tracker_t, zappar_world_tracker_t, zappar_pipeline_t, zappar_image_tracker_t, zappar_sequence_source_t } from "./gen/zappar";
3
3
  export declare type zappar_html_element_source_t = number & {
4
4
  _: 'zappar_html_element_source_t';
@@ -23,6 +23,8 @@ export interface Additional {
23
23
  pipeline_draw_face_project(pipeline: zappar_pipeline_t, drawwMatrix: Float32Array, vertices: Float32Array, uvMatrix: Float32Array, uvs: Float32Array, indices: Uint16Array, texture: WebGLTexture): void;
24
24
  pipeline_camera_frame_data_raw_enabled_set(pipeline: zappar_pipeline_t, enabled: boolean): void;
25
25
  pipeline_camera_frame_data_raw(pipeline: zappar_pipeline_t): Promise<CameraFrameData | undefined>;
26
+ pipeline_camera_frame_data_rgb_enabled_set(pipeline: zappar_pipeline_t, enabled: boolean): void;
27
+ pipeline_camera_frame_data_rgb(pipeline: zappar_pipeline_t): CameraFrameDataRGB | undefined;
26
28
  draw_plane(gl: WebGLRenderingContext, projectionMatrix: Float32Array, cameraMatrix: Float32Array, targetMatrix: Float32Array, texture: string): void;
27
29
  draw_grid(gl: WebGLRenderingContext, projectionMatrix: Float32Array, cameraMatrix: Float32Array, targetMatrix: Float32Array): void;
28
30
  draw_axis(gl: WebGLRenderingContext, projectionMatrix: Float32Array, cameraMatrix: Float32Array, targetMatrix: Float32Array): void;
@@ -1,5 +1,11 @@
1
- export interface CameraFrameData {
1
+ /// <reference types="dom-webcodecs" />
2
+ export interface BaseFrameData {
2
3
  width: number;
3
4
  height: number;
5
+ }
6
+ export interface CameraFrameData extends BaseFrameData {
4
7
  data: ArrayBuffer;
5
8
  }
9
+ export interface CameraFrameDataRGB extends BaseFrameData {
10
+ frame: ImageBitmap | VideoFrame | ImageData;
11
+ }
@@ -16,6 +16,12 @@ export declare class HTMLElementSource extends Source {
16
16
  private _cameraModel;
17
17
  private _profile;
18
18
  private _waitingForFrame;
19
+ private _rgbOffscreenCanvas;
20
+ private _rgbOffscreenContext;
21
+ private _rgbDomCanvas;
22
+ private _rgbDomContext;
23
+ private _currentRgbFrame;
24
+ private _isVideoElement;
19
25
  static createVideoElementSource(p: zappar_pipeline_t, element: HTMLVideoElement | HTMLImageElement): zappar_html_element_source_t;
20
26
  static getVideoElementSource(m: zappar_html_element_source_t): HTMLElementSource | undefined;
21
27
  constructor(_video: HTMLVideoElement | HTMLImageElement, _pipeline: zappar_pipeline_t);
@@ -30,4 +36,7 @@ export declare class HTMLElementSource extends Source {
30
36
  private _processFrame;
31
37
  uploadGL(): void;
32
38
  setProfile(p: camera_profile_t): void;
39
+ private _generateRGBFrame;
40
+ private _generateOffscreenRgbFrame;
41
+ private _generateDomRgbFrame;
33
42
  }
@@ -3,7 +3,7 @@ import { Pipeline } from "./pipeline";
3
3
  import { Source } from "./source";
4
4
  import { profile } from "./profile";
5
5
  import { mat4 } from "gl-matrix";
6
- import { zcout } from "./loglevel";
6
+ import { zcout, zcerr } from "./loglevel";
7
7
  import { ImageProcessGL } from "./image-process-gl";
8
8
  let latest = 1;
9
9
  let byId = new Map();
@@ -22,10 +22,14 @@ export class HTMLElementSource extends Source {
22
22
  this._cameraModel = new Float32Array([300, 300, 160, 120, 0, 0]);
23
23
  this._profile = camera_profile_t.DEFAULT;
24
24
  this._waitingForFrame = false;
25
+ this._rgbOffscreenContext = null;
26
+ this._rgbDomContext = null;
27
+ this._isVideoElement = false;
25
28
  this._lastPresentedFrames = -1;
26
29
  mat4.fromScaling(this._cameraToDeviceTransformUserFacing, [-1, 1, -1]);
27
30
  let video = this._video;
28
- if (this._video instanceof HTMLVideoElement) {
31
+ this._isVideoElement = video instanceof HTMLVideoElement;
32
+ if (this._isVideoElement) {
29
33
  video.addEventListener("loadedmetadata", () => { this._hadFrames = true; });
30
34
  }
31
35
  else {
@@ -56,6 +60,11 @@ export class HTMLElementSource extends Source {
56
60
  p.onGLContextReset.unbind(this._resetGLContext);
57
61
  this.pause();
58
62
  this._resetGLContext();
63
+ this._currentRgbFrame = undefined;
64
+ this._rgbDomCanvas = undefined;
65
+ this._rgbDomContext = null;
66
+ this._rgbOffscreenCanvas = undefined;
67
+ this._rgbOffscreenContext = null;
59
68
  }
60
69
  pause() {
61
70
  this._isPaused = true;
@@ -138,6 +147,8 @@ export class HTMLElementSource extends Source {
138
147
  }
139
148
  if (!this._currentVideoTexture)
140
149
  return undefined;
150
+ if (pipeline.getCameraFrameDataRGBEnabled())
151
+ this._currentRgbFrame = this._generateRGBFrame();
141
152
  this._imageProcessor.uploadFrame(this._currentVideoTexture, this._video, rotation, this._isUserFacing, this._profile);
142
153
  this._requestVideoFrameCallback();
143
154
  this._isUploadFrame = !this._isUploadFrame;
@@ -164,7 +175,12 @@ export class HTMLElementSource extends Source {
164
175
  this._cameraModel[1] = focalLength;
165
176
  this._cameraModel[2] = dataWidth * 0.5;
166
177
  this._cameraModel[3] = dataHeight * 0.5;
167
- return Object.assign(Object.assign({}, this._imageProcessor.readFrame(tex, pixels, this._profile)), { cameraModel: this._cameraModel, cameraSource: this, cameraToDevice: (this._isUserFacing ? this._cameraToDeviceTransformUserFacing : this._cameraToDeviceTransform) });
178
+ const info = Object.assign(Object.assign({}, this._imageProcessor.readFrame(tex, pixels, this._profile)), { cameraModel: this._cameraModel, cameraSource: this, cameraToDevice: (this._isUserFacing ? this._cameraToDeviceTransformUserFacing : this._cameraToDeviceTransform) });
179
+ if (this._currentRgbFrame) {
180
+ info.rgbFrame = this._currentRgbFrame;
181
+ this._currentRgbFrame = undefined;
182
+ }
183
+ return info;
168
184
  }
169
185
  uploadGL() {
170
186
  // No-op as already uploaded
@@ -172,4 +188,57 @@ export class HTMLElementSource extends Source {
172
188
  setProfile(p) {
173
189
  this._profile = p;
174
190
  }
191
+ _generateRGBFrame() {
192
+ const width = this._isVideoElement ? this._video.videoWidth : this._video.naturalWidth;
193
+ const height = this._isVideoElement ? this._video.videoHeight : this._video.naturalHeight;
194
+ if (!(width > 0 && height > 0))
195
+ return undefined;
196
+ return profile.offscreenCanvasSupported
197
+ ? this._generateOffscreenRgbFrame(width, height)
198
+ : this._generateDomRgbFrame(width, height);
199
+ }
200
+ _generateOffscreenRgbFrame(width, height) {
201
+ var _a;
202
+ if (!this._rgbOffscreenCanvas) {
203
+ this._rgbOffscreenCanvas = new OffscreenCanvas(width, height);
204
+ this._rgbOffscreenContext = this._rgbOffscreenCanvas.getContext('2d', {
205
+ alpha: false,
206
+ willReadFrequently: true
207
+ });
208
+ }
209
+ else if (this._rgbOffscreenCanvas.width !== width || this._rgbOffscreenCanvas.height !== height) {
210
+ this._rgbOffscreenCanvas.width = width;
211
+ this._rgbOffscreenCanvas.height = height;
212
+ }
213
+ (_a = this._rgbOffscreenContext) === null || _a === void 0 ? void 0 : _a.drawImage(this._video, 0, 0, width, height);
214
+ try {
215
+ return this._rgbOffscreenCanvas.transferToImageBitmap();
216
+ }
217
+ catch (e) {
218
+ zcerr(`Failed to generate RGB frame: ${e}`);
219
+ return undefined;
220
+ }
221
+ }
222
+ _generateDomRgbFrame(width, height) {
223
+ var _a, _b;
224
+ if (!this._rgbDomCanvas) {
225
+ this._rgbDomCanvas = document.createElement('canvas');
226
+ this._rgbDomContext = this._rgbDomCanvas.getContext('2d', {
227
+ alpha: false,
228
+ willReadFrequently: true
229
+ });
230
+ }
231
+ else if (this._rgbDomCanvas.width !== width || this._rgbDomCanvas.height !== height) {
232
+ this._rgbDomCanvas.width = width;
233
+ this._rgbDomCanvas.height = height;
234
+ }
235
+ (_a = this._rgbDomContext) === null || _a === void 0 ? void 0 : _a.drawImage(this._video, 0, 0, width, height);
236
+ try {
237
+ return (_b = this._rgbDomContext) === null || _b === void 0 ? void 0 : _b.getImageData(0, 0, width, height);
238
+ }
239
+ catch (e) {
240
+ zcerr(`Failed to generate RGB frame: ${e}`);
241
+ return undefined;
242
+ }
243
+ }
175
244
  }
@@ -286,8 +286,6 @@ export class ImageBitmapCameraSource extends Source {
286
286
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, info.frame);
287
287
  gl.bindTexture(gl.TEXTURE_2D, null);
288
288
  info.texture = texture;
289
- info.frame.close();
290
- delete info.frame;
291
289
  }
292
290
  }
293
291
  ImageBitmapCameraSource.USER_DEFAULT_DEVICE_ID = "Simulated User Default Device ID: a908df7f-5661-4d20-b227-a1c15d2fdb4b";
@@ -323,8 +323,6 @@ export class MSTPCameraSource extends Source {
323
323
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, info.frame);
324
324
  gl.bindTexture(gl.TEXTURE_2D, previousBoundTexture);
325
325
  info.texture = texture;
326
- info.frame.close();
327
- delete info.frame;
328
326
  }
329
327
  }
330
328
  MSTPCameraSource.USER_DEFAULT_DEVICE_ID = "Simulated User Default Device ID: a908df7f-5661-4d20-b227-a1c15d2fdb4b";
package/lib/native.js CHANGED
@@ -277,7 +277,7 @@ export function initialize(opts) {
277
277
  return;
278
278
  }
279
279
  (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.drawImageTargetPreview(projectionMatrix, cameraMatrix, targetMatrix, indx, obj);
280
- }, projection_matrix_from_camera_model_and_size: projectionMatrixFromModelAndSize, projection_matrix_from_camera_model_and_size_ext: projectionMatrixFromModelAndSize, pipeline_process_gl: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.processGL(); }, pipeline_gl_context_set: (p, gl, texturePool) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.glContextSet(gl, texturePool); }, pipeline_gl_context_lost: (p) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.glContextLost(); }, pipeline_camera_frame_upload_gl: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.uploadGL(); }, pipeline_camera_frame_texture_gl: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.cameraFrameTexture(); }, pipeline_camera_frame_texture_matrix: (p, sw, sh, mirror) => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.cameraFrameTextureMatrix(sw, sh, mirror)) || mat4.create(); }, pipeline_camera_frame_user_facing: p => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.cameraFrameUserFacing()) || false; }, pipeline_camera_pose_default: () => mat4.create(), pipeline_camera_pose_with_attitude: (p, mirror) => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.cameraPoseWithAttitude(mirror)) || mat4.create(); }, pipeline_camera_pose_with_origin: (p, o) => { let res = mat4.create(); mat4.invert(res, o); return res; }, pipeline_sequence_record_clear: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordClear(); }, pipeline_sequence_record_start: (p, expectedFrames) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordStart(expectedFrames); }, pipeline_sequence_record_stop: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordStop(); }, pipeline_sequence_record_device_attitude_matrices_set: (p, v) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordDeviceAttitudeMatrices(v); }, pipeline_sequence_record_data: p => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordData()) || new Uint8Array(0); }, pipeline_sequence_record_data_size: p => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordData().byteLength) || 0; }, pipeline_camera_frame_data_raw: p => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.getCameraFrameDataRaw()) || Promise.reject(); }, pipeline_camera_frame_data_raw_enabled_set: (p, v) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.setCameraFrameDataRawEnabled(v); }, instant_world_tracker_anchor_pose_camera_relative: (o, mirror) => {
280
+ }, projection_matrix_from_camera_model_and_size: projectionMatrixFromModelAndSize, projection_matrix_from_camera_model_and_size_ext: projectionMatrixFromModelAndSize, pipeline_process_gl: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.processGL(); }, pipeline_gl_context_set: (p, gl, texturePool) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.glContextSet(gl, texturePool); }, pipeline_gl_context_lost: (p) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.glContextLost(); }, pipeline_camera_frame_upload_gl: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.uploadGL(); }, pipeline_camera_frame_texture_gl: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.cameraFrameTexture(); }, pipeline_camera_frame_texture_matrix: (p, sw, sh, mirror) => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.cameraFrameTextureMatrix(sw, sh, mirror)) || mat4.create(); }, pipeline_camera_frame_user_facing: p => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.cameraFrameUserFacing()) || false; }, pipeline_camera_pose_default: () => mat4.create(), pipeline_camera_pose_with_attitude: (p, mirror) => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.cameraPoseWithAttitude(mirror)) || mat4.create(); }, pipeline_camera_pose_with_origin: (p, o) => { let res = mat4.create(); mat4.invert(res, o); return res; }, pipeline_sequence_record_clear: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordClear(); }, pipeline_sequence_record_start: (p, expectedFrames) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordStart(expectedFrames); }, pipeline_sequence_record_stop: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordStop(); }, pipeline_sequence_record_device_attitude_matrices_set: (p, v) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordDeviceAttitudeMatrices(v); }, pipeline_sequence_record_data: p => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordData()) || new Uint8Array(0); }, pipeline_sequence_record_data_size: p => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.sequenceRecordData().byteLength) || 0; }, pipeline_camera_frame_data_raw: p => { var _a; return ((_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.getCameraFrameDataRaw()) || Promise.reject(); }, pipeline_camera_frame_data_raw_enabled_set: (p, v) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.setCameraFrameDataRawEnabled(v); }, pipeline_camera_frame_data_rgb: p => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.getCameraFrameDataRGB(); }, pipeline_camera_frame_data_rgb_enabled_set: (p, v) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.setCameraFrameDataRGBEnabled(v); }, instant_world_tracker_anchor_pose_camera_relative: (o, mirror) => {
281
281
  let res = applyScreenCounterRotation(undefined, c.impl.instant_world_tracker_anchor_pose_raw(o));
282
282
  if (mirror) {
283
283
  let scale = mat4.create();
@@ -456,8 +456,8 @@ export function initialize(opts) {
456
456
  }
457
457
  }
458
458
  }
459
- if (!anchor_pose) {
460
- zcwarn("unable for find anchor with id", anchor_id);
459
+ if (!anchor_pose || anchor_pose.length !== 16) {
460
+ zcwarn("unable for find valid pose for anchor with id", anchor_id);
461
461
  return;
462
462
  }
463
463
  const pose = mat4.create();
package/lib/pipeline.d.ts CHANGED
@@ -9,7 +9,7 @@ import { FaceMesh } from "./facemesh";
9
9
  import { Event } from "./event";
10
10
  import { ImageTracker } from "./imagetracker";
11
11
  import { zappar } from "./gen/zappar-bridge";
12
- import { CameraFrameData } from "./camera-frame-data";
12
+ import { CameraFrameData, CameraFrameDataRGB } from "./camera-frame-data";
13
13
  export declare class Pipeline {
14
14
  private _client;
15
15
  private _impl;
@@ -33,6 +33,7 @@ export declare class Pipeline {
33
33
  private _cameraFrameDataResolves;
34
34
  private _cameraFrameDataRejects;
35
35
  private _cameraFrameDataEnabled;
36
+ private _cameraFrameDataRGBEnabled;
36
37
  onGLContextReset: Event;
37
38
  static create(client: zappar, mgr: MsgManager): zappar_pipeline_t;
38
39
  static get(p: zappar_pipeline_t): Pipeline | undefined;
@@ -47,6 +48,9 @@ export declare class Pipeline {
47
48
  sequenceRecordClear(): void;
48
49
  sequenceRecordDeviceAttitudeMatrices(v: boolean): void;
49
50
  getVideoTexture(): WebGLTexture | undefined;
51
+ getCameraFrameDataRGB(): CameraFrameDataRGB | undefined;
52
+ setCameraFrameDataRGBEnabled(e: boolean): void;
53
+ getCameraFrameDataRGBEnabled(): boolean;
50
54
  getCameraFrameDataRaw(): Promise<CameraFrameData | undefined>;
51
55
  setCameraFrameDataRawEnabled(e: boolean): void;
52
56
  destroy(): void;
package/lib/pipeline.js CHANGED
@@ -28,6 +28,7 @@ export class Pipeline {
28
28
  this._cameraFrameDataResolves = new Map();
29
29
  this._cameraFrameDataRejects = new Map();
30
30
  this._cameraFrameDataEnabled = false;
31
+ this._cameraFrameDataRGBEnabled = false;
31
32
  this.onGLContextReset = new Event();
32
33
  }
33
34
  static create(client, mgr) {
@@ -51,7 +52,7 @@ export class Pipeline {
51
52
  this.cleanOldFrames();
52
53
  }
53
54
  cleanOldFrames() {
54
- var _a, _b, _c, _d;
55
+ var _a, _b, _c, _d, _e, _f;
55
56
  let currentToken = this._client.pipeline_camera_frame_user_data(this._impl);
56
57
  if (!currentToken)
57
58
  return;
@@ -60,7 +61,17 @@ export class Pipeline {
60
61
  if (t[1].texture)
61
62
  this.videoTextures.push(t[1].texture);
62
63
  (_b = (_a = t[1].frame) === null || _a === void 0 ? void 0 : _a.close) === null || _b === void 0 ? void 0 : _b.call(_a);
63
- (_d = (_c = t[1].cameraSource).recycle) === null || _d === void 0 ? void 0 : _d.call(_c, t[1]);
64
+ if (t[1].frame !== t[1].rgbFrame) {
65
+ if (t[1].rgbFrame instanceof ImageData) {
66
+ // auto gc'd
67
+ }
68
+ else {
69
+ (_d = (_c = t[1].rgbFrame) === null || _c === void 0 ? void 0 : _c.close) === null || _d === void 0 ? void 0 : _d.call(_c);
70
+ }
71
+ }
72
+ t[1].frame = undefined;
73
+ t[1].rgbFrame = undefined;
74
+ (_f = (_e = t[1].cameraSource).recycle) === null || _f === void 0 ? void 0 : _f.call(_e, t[1]);
64
75
  if (t[1].data) {
65
76
  this.cameraPixelArrays.push(t[1].data);
66
77
  t[1].data = undefined;
@@ -135,6 +146,34 @@ export class Pipeline {
135
146
  getVideoTexture() {
136
147
  return this.videoTextures.pop();
137
148
  }
149
+ getCameraFrameDataRGB() {
150
+ if (!this._cameraFrameDataRGBEnabled)
151
+ return undefined;
152
+ const info = this.getCurrentCameraInfo();
153
+ if (!info || !info.rgbFrame)
154
+ return undefined;
155
+ let width = 0;
156
+ let height = 0;
157
+ if (info.rgbFrame instanceof VideoFrame) {
158
+ width = info.rgbFrame.displayWidth;
159
+ height = info.rgbFrame.displayHeight;
160
+ }
161
+ else {
162
+ width = info.rgbFrame.width;
163
+ height = info.rgbFrame.height;
164
+ }
165
+ return {
166
+ frame: info.rgbFrame,
167
+ width,
168
+ height,
169
+ };
170
+ }
171
+ setCameraFrameDataRGBEnabled(e) {
172
+ this._cameraFrameDataRGBEnabled = e;
173
+ }
174
+ getCameraFrameDataRGBEnabled() {
175
+ return this._cameraFrameDataRGBEnabled;
176
+ }
138
177
  getCameraFrameDataRaw() {
139
178
  if (!this._cameraFrameDataEnabled)
140
179
  throw new Error('Raw camera frame data is not enabled.');
@@ -297,6 +336,7 @@ export class Pipeline {
297
336
  cameraToDevice: msg.cameraToDevice,
298
337
  cameraSource,
299
338
  remoteToken: msg.token,
339
+ rgbFrame: this._cameraFrameDataRGBEnabled ? msg.d : undefined,
300
340
  });
301
341
  this.cleanOldFrames();
302
342
  }
@@ -309,6 +349,8 @@ export class Pipeline {
309
349
  data.frame = msg.frame;
310
350
  data.userFacing = msg.userFacing;
311
351
  data.uvTransform = msg.uvTransform;
352
+ if (this._cameraFrameDataRGBEnabled)
353
+ data.rgbFrame = msg.frame;
312
354
  this.tokensInFlight--;
313
355
  this.cleanOldFrames();
314
356
  }
package/lib/profile.d.ts CHANGED
@@ -20,4 +20,5 @@ export declare let profile: {
20
20
  forceWindowOrientation: boolean;
21
21
  intervalMultiplier: number;
22
22
  trustSensorIntervals: boolean;
23
+ offscreenCanvasSupported: boolean;
23
24
  };
package/lib/profile.js CHANGED
@@ -23,6 +23,7 @@ export let profile = {
23
23
  forceWindowOrientation: false,
24
24
  intervalMultiplier: 1,
25
25
  trustSensorIntervals: false,
26
+ offscreenCanvasSupported: typeof globalThis.OffscreenCanvas !== "undefined",
26
27
  };
27
28
  if (typeof window !== "undefined") {
28
29
  window["zeeProfile"] = profile;
package/lib/source.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /// <reference types="dom-webcodecs" />
2
2
  export interface CameraFrameInfo {
3
+ rgbFrame?: ImageBitmap | VideoFrame | ImageData;
3
4
  data?: ArrayBuffer;
4
5
  texture: WebGLTexture | undefined;
5
6
  dataWidth: number;
package/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "3.2.0-beta.3";
1
+ export declare const VERSION = "3.3.0-beta.1";
package/lib/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "3.2.0-beta.3";
1
+ export const VERSION = "3.3.0-beta.1";
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zappar/zappar-cv",
3
- "version": "3.2.0-beta.3",
3
+ "version": "3.3.0-beta.1",
4
4
  "description": "Zappar's core computer vision library, supporting image, face and world tracking.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -31,7 +31,6 @@
31
31
  "devDependencies": {
32
32
  "@playwright/test": "^1.48.2",
33
33
  "@types/dom-mediacapture-transform": "0.1.1",
34
- "@types/dom-webcodecs": "0.1.2",
35
34
  "@types/node": "14.14.7",
36
35
  "@types/offscreencanvas": "2019.6.4",
37
36
  "@types/pngjs": "6.0.0",
@@ -47,7 +46,8 @@
47
46
  "webpack": "5.89.0",
48
47
  "webpack-cli": "4.9.2",
49
48
  "webpack-dev-server": "^4.7.3",
50
- "worker-loader": "^3.0.8"
49
+ "worker-loader": "^3.0.8",
50
+ "@types/dom-webcodecs": "0.1.2"
51
51
  },
52
52
  "dependencies": {
53
53
  "@types/w3c-generic-sensor": "^1.0.9",