@webex/ladon-ts 5.5.0 → 5.5.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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### 5.5.1 (2025-05-06)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * issue with 640x480 resolution ([#63](https://github.com/beyonddunbar/ladon-ts/issues/63)) ([5d479d7](https://github.com/beyonddunbar/ladon-ts/commit/5d479d7c68c1e50a4c7b6c90cf132f0775e0b5df))
11
+
5
12
  ### 5.5.0 (2025-04-16)
6
13
 
7
14
 
@@ -4,8 +4,8 @@ import { PassthroughRenderer as u } from "./renderer/passthrough-renderer.js";
4
4
  import { ReplacementRenderer as o } from "./renderer/replacement-renderer.js";
5
5
  import { resizeImage as d } from "./util.js";
6
6
  class k {
7
- constructor(e, t, s, i) {
8
- this.inputCanvas = e, this.outputCanvas = t, this.config = s, this.videoElement = i, this.loaded = !1, this.frameQueue = [], this.maskQueue = [];
7
+ constructor(e, t, s, r) {
8
+ this.inputCanvas = e, this.outputCanvas = t, this.config = s, this.videoElement = r, this.loaded = !1, this.frameQueue = [], this.maskQueue = [];
9
9
  const a = this.inputCanvas.getContext("2d", {
10
10
  alpha: !1,
11
11
  willReadFrequently: !0
@@ -27,8 +27,8 @@ class k {
27
27
  throw new Error("[ladon-ts] - pipeline is not loaded.");
28
28
  const s = this.getInputFrameData(t);
29
29
  if (s instanceof Uint8ClampedArray ? ((!this.frameDataBuffer || this.frameDataBuffer.length !== s.length) && (this.frameDataBuffer = new Uint8ClampedArray(s.length)), this.frameDataBuffer.set(s), this.frameQueue.push({ timestamp: e, frameData: this.frameDataBuffer })) : this.frameQueue.push({ timestamp: e, frameData: s }), t || !this.lastMaskResult) {
30
- const i = s, a = this.getMaskImageData(i), r = await this.generator.getLadonOutput(a, e);
31
- this.maskQueue.push({ timestamp: r.timestamp, maskResult: r }), this.lastMaskResult = r, await this.renderSyncedFrameAndMask(), await this.generator.postRender(a, e);
30
+ const r = s, a = this.getMaskImageData(r), i = await this.generator.getLadonOutput(a, e);
31
+ this.maskQueue.push({ timestamp: i.timestamp, maskResult: i }), this.lastMaskResult = i, await this.renderSyncedFrameAndMask(), await this.generator.postRender(a, e);
32
32
  } else
33
33
  this.maskQueue.push({ timestamp: e, maskResult: this.lastMaskResult }), await this.renderSyncedFrameAndMask();
34
34
  return this.createInferenceResult(e, t);
@@ -65,12 +65,13 @@ class k {
65
65
  * @returns {Uint8ClampedArray} - The processed mask image data.
66
66
  */
67
67
  getMaskImageData(e) {
68
- return this.config.mask.inputSize.width === this.config.input.width ? e : d(
68
+ const t = this.config.mask.inputSize, s = this.config.input;
69
+ return t.width === s.width && t.height === s.height ? e : d(
69
70
  e,
70
- this.config.input.width,
71
- this.config.input.height,
72
- this.config.mask.inputSize.width,
73
- this.config.mask.inputSize.height
71
+ s.width,
72
+ s.height,
73
+ t.width,
74
+ t.height
74
75
  );
75
76
  }
76
77
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.js","sources":["../../../src/lib/pipeline.ts"],"sourcesContent":["import { PipelineConfig } from './config-types';\nimport {\n FacesAndLandmarks,\n FrameData,\n LadonOutput,\n MaskGenerator,\n WorkerGenerator,\n} from './generator';\nimport { BlurRenderer, LadonRenderer, PassthroughRenderer, ReplacementRenderer } from './renderer';\nimport { resizeImage } from './util';\n\nexport interface IFrameInferenceResult {\n facesAndLandmarks: FacesAndLandmarks;\n gesture: Float32Array;\n motion: number;\n skipped: boolean;\n timestamp: number;\n}\n\nexport interface IPipeline {\n onFrame(timestamp: number, maskNeeded?: boolean): Promise<IFrameInferenceResult>;\n isLoaded(): boolean;\n load(): Promise<void>;\n destroy(): void;\n}\n\nexport class Pipeline implements IPipeline {\n private generator?: MaskGenerator;\n private renderer?: LadonRenderer;\n private loaded = false;\n\n private inputCanvasCtx: CanvasRenderingContext2D;\n private lastMaskResult?: LadonOutput;\n\n private frameQueue: Array<{ timestamp: number; frameData: FrameData }> = [];\n private maskQueue: Array<{ timestamp: number; maskResult: LadonOutput }> = [];\n\n private frameDataBuffer?: Uint8ClampedArray;\n\n constructor(\n private inputCanvas: HTMLCanvasElement,\n private outputCanvas: HTMLCanvasElement,\n public readonly config: PipelineConfig,\n private readonly videoElement?: HTMLVideoElement\n ) {\n const inputCanvasCtx = this.inputCanvas.getContext('2d', {\n alpha: false,\n willReadFrequently: true,\n });\n\n if (!inputCanvasCtx) {\n throw new Error('[ladon-ts] - error getting input context 2d');\n }\n this.inputCanvasCtx = inputCanvasCtx;\n }\n\n /**\n * Processes a single frame and returns the inference result.\n *\n * @param timestamp - The timestamp of the frame.\n * @param performInference - Flag to perform mask inference.\n * @returns The result of the frame processing.\n * @throws If the pipeline (generator or renderer) is not loaded.\n */\n public async onFrame(\n timestamp: number,\n performInference = true\n ): Promise<IFrameInferenceResult> {\n if (!this.generator || !this.renderer) {\n throw new Error('[ladon-ts] - pipeline is not loaded.');\n }\n\n // Get the current frame (raw image data or video element)\n const frameData = this.getInputFrameData(performInference);\n\n // Reuse or create buffer for frame data copies, which is needed to ensure the data is not modified\n // or garbage collected before the inference is done.\n if (frameData instanceof Uint8ClampedArray) {\n if (!this.frameDataBuffer || this.frameDataBuffer.length !== frameData.length) {\n this.frameDataBuffer = new Uint8ClampedArray(frameData.length);\n }\n this.frameDataBuffer.set(frameData);\n this.frameQueue.push({ timestamp, frameData: this.frameDataBuffer });\n } else {\n // For video elements, just pass the reference\n this.frameQueue.push({ timestamp, frameData });\n }\n\n if (performInference || !this.lastMaskResult) {\n // Perform inference and add the new mask to the mask queue\n const rawImageData = frameData as Uint8ClampedArray;\n const maskImageData = this.getMaskImageData(rawImageData);\n const maskResult = await this.generator.getLadonOutput(maskImageData, timestamp);\n // Add the mask to the queue and use the mask timestamp to sync frames and masks.\n this.maskQueue.push({ timestamp: maskResult.timestamp, maskResult });\n this.lastMaskResult = maskResult;\n\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n\n // Post-process the mask after rendering\n await this.generator.postRender(maskImageData, timestamp);\n } else {\n // Skipping inference. Update the last mask result's timestamp to match the current frame.\n this.maskQueue.push({ timestamp, maskResult: this.lastMaskResult });\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n }\n\n // Return the inference result\n return this.createInferenceResult(timestamp, performInference);\n }\n\n /**\n * Synchronizes frames and masks to ensure they are rendered together.\n */\n private async renderSyncedFrameAndMask(): Promise<void> {\n while (this.frameQueue.length > 0 && this.maskQueue.length > 0) {\n const frame = this.frameQueue[0];\n const maskEntry = this.maskQueue[0];\n\n if (frame.timestamp === maskEntry.timestamp) {\n // Render the frame and mask together\n await this.renderer?.render(frame.frameData, maskEntry.maskResult);\n this.frameQueue.shift();\n this.maskQueue.shift();\n } else if (frame.timestamp < maskEntry.timestamp) {\n // Discard the older frame\n this.frameQueue.shift();\n } else {\n // Discard the older mask\n this.maskQueue.shift();\n }\n }\n }\n\n /**\n * Gets the raw image data from the input canvas context.\n *\n * @param needFreshImageData - Flag to indicate if fresh image data is needed.\n *\n * @returns The raw image data.\n */\n private getInputFrameData(needFreshImageData: boolean): FrameData {\n if (needFreshImageData || !this.videoElement) {\n return this.inputCanvasCtx.getImageData(\n 0,\n 0,\n this.config.input.width,\n this.config.input.height\n ).data;\n }\n\n return this.videoElement;\n }\n\n /**\n * Resizes the image data if the model expects a fixed size input.\n *\n * @param {Uint8ClampedArray} rawImageData - The raw image data.\n * @returns {Uint8ClampedArray} - The processed mask image data.\n */\n private getMaskImageData(rawImageData: Uint8ClampedArray): Uint8ClampedArray {\n // Check if resizing is needed based on configuration.\n if (this.config.mask.inputSize.width === this.config.input.width) {\n return rawImageData;\n }\n\n // Resize the image data.\n return resizeImage(\n rawImageData,\n this.config.input.width,\n this.config.input.height,\n this.config.mask.inputSize.width,\n this.config.mask.inputSize.height\n );\n }\n\n /**\n * Creates the inference result object.\n *\n * @param {number} timestamp - The timestamp of the frame.\n * @param {boolean} performedInference - Indicates if the inference was performed.\n * @returns {IFrameInferenceResult} - The result object containing inference details.\n */\n private createInferenceResult(\n timestamp: number,\n performedInference: boolean\n ): IFrameInferenceResult {\n if (!this.lastMaskResult) {\n return {\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n skipped: true,\n timestamp,\n };\n }\n\n return {\n facesAndLandmarks: this.lastMaskResult.facesAndLandmarks,\n gesture: this.lastMaskResult.gesture,\n motion: this.lastMaskResult.motion,\n skipped: !performedInference,\n timestamp,\n };\n }\n\n /**\n * Checks if the pipeline is loaded.\n *\n * @returns True if the pipeline is loaded, false otherwise.\n */\n public isLoaded(): boolean {\n return this.loaded;\n }\n\n /**\n * Loads the pipeline components such as the generator and renderer.\n */\n public async load(): Promise<void> {\n switch (this.config.render.type) {\n case 'blur':\n this.renderer = new BlurRenderer(this.outputCanvas, this.config);\n break;\n case 'passthrough':\n this.renderer = new PassthroughRenderer(this.outputCanvas, this.config);\n break;\n case 'replacement':\n this.renderer = new ReplacementRenderer(this.outputCanvas, this.config);\n break;\n default:\n throw new Error('[ladon-ts] - renderer not implemented.');\n }\n\n await this.renderer.load();\n\n this.generator = new WorkerGenerator(this.config);\n await this.generator.load();\n\n this.loaded = true;\n }\n\n /**\n * Resets the frame and mask queues.\n */\n private resetQueues(): void {\n this.frameQueue = [];\n this.maskQueue = [];\n }\n\n public reset(): void {\n this.resetQueues();\n this.lastMaskResult = undefined;\n }\n\n /**\n * Destroys the pipeline and cleans up resources.\n */\n public destroy(): void {\n this.reset();\n this.generator?.destroy();\n this.renderer?.destroy();\n this.frameDataBuffer = undefined;\n }\n}\n"],"names":["Pipeline","inputCanvas","outputCanvas","config","videoElement","inputCanvasCtx","timestamp","performInference","frameData","rawImageData","maskImageData","maskResult","frame","maskEntry","_a","needFreshImageData","resizeImage","performedInference","BlurRenderer","PassthroughRenderer","ReplacementRenderer","WorkerGenerator","_b"],"mappings":"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"}
1
+ {"version":3,"file":"pipeline.js","sources":["../../../src/lib/pipeline.ts"],"sourcesContent":["import { PipelineConfig } from './config-types';\nimport {\n FacesAndLandmarks,\n FrameData,\n LadonOutput,\n MaskGenerator,\n WorkerGenerator,\n} from './generator';\nimport { BlurRenderer, LadonRenderer, PassthroughRenderer, ReplacementRenderer } from './renderer';\nimport { resizeImage } from './util';\n\nexport interface IFrameInferenceResult {\n facesAndLandmarks: FacesAndLandmarks;\n gesture: Float32Array;\n motion: number;\n skipped: boolean;\n timestamp: number;\n}\n\nexport interface IPipeline {\n onFrame(timestamp: number, maskNeeded?: boolean): Promise<IFrameInferenceResult>;\n isLoaded(): boolean;\n load(): Promise<void>;\n destroy(): void;\n}\n\nexport class Pipeline implements IPipeline {\n private generator?: MaskGenerator;\n private renderer?: LadonRenderer;\n private loaded = false;\n\n private inputCanvasCtx: CanvasRenderingContext2D;\n private lastMaskResult?: LadonOutput;\n\n private frameQueue: Array<{ timestamp: number; frameData: FrameData }> = [];\n private maskQueue: Array<{ timestamp: number; maskResult: LadonOutput }> = [];\n\n private frameDataBuffer?: Uint8ClampedArray;\n\n constructor(\n private inputCanvas: HTMLCanvasElement,\n private outputCanvas: HTMLCanvasElement,\n public readonly config: PipelineConfig,\n private readonly videoElement?: HTMLVideoElement\n ) {\n const inputCanvasCtx = this.inputCanvas.getContext('2d', {\n alpha: false,\n willReadFrequently: true,\n });\n\n if (!inputCanvasCtx) {\n throw new Error('[ladon-ts] - error getting input context 2d');\n }\n this.inputCanvasCtx = inputCanvasCtx;\n }\n\n /**\n * Processes a single frame and returns the inference result.\n *\n * @param timestamp - The timestamp of the frame.\n * @param performInference - Flag to perform mask inference.\n * @returns The result of the frame processing.\n * @throws If the pipeline (generator or renderer) is not loaded.\n */\n public async onFrame(\n timestamp: number,\n performInference = true\n ): Promise<IFrameInferenceResult> {\n if (!this.generator || !this.renderer) {\n throw new Error('[ladon-ts] - pipeline is not loaded.');\n }\n\n // Get the current frame (raw image data or video element)\n const frameData = this.getInputFrameData(performInference);\n\n // Reuse or create buffer for frame data copies, which is needed to ensure the data is not modified\n // or garbage collected before the inference is done.\n if (frameData instanceof Uint8ClampedArray) {\n if (!this.frameDataBuffer || this.frameDataBuffer.length !== frameData.length) {\n this.frameDataBuffer = new Uint8ClampedArray(frameData.length);\n }\n this.frameDataBuffer.set(frameData);\n this.frameQueue.push({ timestamp, frameData: this.frameDataBuffer });\n } else {\n // For video elements, just pass the reference\n this.frameQueue.push({ timestamp, frameData });\n }\n\n if (performInference || !this.lastMaskResult) {\n // Perform inference and add the new mask to the mask queue\n const rawImageData = frameData as Uint8ClampedArray;\n const maskImageData = this.getMaskImageData(rawImageData);\n const maskResult = await this.generator.getLadonOutput(maskImageData, timestamp);\n // Add the mask to the queue and use the mask timestamp to sync frames and masks.\n this.maskQueue.push({ timestamp: maskResult.timestamp, maskResult });\n this.lastMaskResult = maskResult;\n\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n\n // Post-process the mask after rendering\n await this.generator.postRender(maskImageData, timestamp);\n } else {\n // Skipping inference. Update the last mask result's timestamp to match the current frame.\n this.maskQueue.push({ timestamp, maskResult: this.lastMaskResult });\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n }\n\n // Return the inference result\n return this.createInferenceResult(timestamp, performInference);\n }\n\n /**\n * Synchronizes frames and masks to ensure they are rendered together.\n */\n private async renderSyncedFrameAndMask(): Promise<void> {\n while (this.frameQueue.length > 0 && this.maskQueue.length > 0) {\n const frame = this.frameQueue[0];\n const maskEntry = this.maskQueue[0];\n\n if (frame.timestamp === maskEntry.timestamp) {\n // Render the frame and mask together\n await this.renderer?.render(frame.frameData, maskEntry.maskResult);\n this.frameQueue.shift();\n this.maskQueue.shift();\n } else if (frame.timestamp < maskEntry.timestamp) {\n // Discard the older frame\n this.frameQueue.shift();\n } else {\n // Discard the older mask\n this.maskQueue.shift();\n }\n }\n }\n\n /**\n * Gets the raw image data from the input canvas context.\n *\n * @param needFreshImageData - Flag to indicate if fresh image data is needed.\n *\n * @returns The raw image data.\n */\n private getInputFrameData(needFreshImageData: boolean): FrameData {\n if (needFreshImageData || !this.videoElement) {\n return this.inputCanvasCtx.getImageData(\n 0,\n 0,\n this.config.input.width,\n this.config.input.height\n ).data;\n }\n\n return this.videoElement;\n }\n\n /**\n * Resizes the image data if the model expects a fixed size input.\n *\n * @param {Uint8ClampedArray} rawImageData - The raw image data.\n * @returns {Uint8ClampedArray} - The processed mask image data.\n */\n private getMaskImageData(rawImageData: Uint8ClampedArray): Uint8ClampedArray {\n const modelInput = this.config.mask.inputSize;\n const inputImage = this.config.input;\n\n // Check if resizing is needed based on configuration.\n if (modelInput.width === inputImage.width && modelInput.height === inputImage.height) {\n return rawImageData;\n }\n\n // Resize the image data.\n return resizeImage(\n rawImageData,\n inputImage.width,\n inputImage.height,\n modelInput.width,\n modelInput.height\n );\n }\n\n /**\n * Creates the inference result object.\n *\n * @param {number} timestamp - The timestamp of the frame.\n * @param {boolean} performedInference - Indicates if the inference was performed.\n * @returns {IFrameInferenceResult} - The result object containing inference details.\n */\n private createInferenceResult(\n timestamp: number,\n performedInference: boolean\n ): IFrameInferenceResult {\n if (!this.lastMaskResult) {\n return {\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n skipped: true,\n timestamp,\n };\n }\n\n return {\n facesAndLandmarks: this.lastMaskResult.facesAndLandmarks,\n gesture: this.lastMaskResult.gesture,\n motion: this.lastMaskResult.motion,\n skipped: !performedInference,\n timestamp,\n };\n }\n\n /**\n * Checks if the pipeline is loaded.\n *\n * @returns True if the pipeline is loaded, false otherwise.\n */\n public isLoaded(): boolean {\n return this.loaded;\n }\n\n /**\n * Loads the pipeline components such as the generator and renderer.\n */\n public async load(): Promise<void> {\n switch (this.config.render.type) {\n case 'blur':\n this.renderer = new BlurRenderer(this.outputCanvas, this.config);\n break;\n case 'passthrough':\n this.renderer = new PassthroughRenderer(this.outputCanvas, this.config);\n break;\n case 'replacement':\n this.renderer = new ReplacementRenderer(this.outputCanvas, this.config);\n break;\n default:\n throw new Error('[ladon-ts] - renderer not implemented.');\n }\n\n await this.renderer.load();\n\n this.generator = new WorkerGenerator(this.config);\n await this.generator.load();\n\n this.loaded = true;\n }\n\n /**\n * Resets the frame and mask queues.\n */\n private resetQueues(): void {\n this.frameQueue = [];\n this.maskQueue = [];\n }\n\n public reset(): void {\n this.resetQueues();\n this.lastMaskResult = undefined;\n }\n\n /**\n * Destroys the pipeline and cleans up resources.\n */\n public destroy(): void {\n this.reset();\n this.generator?.destroy();\n this.renderer?.destroy();\n this.frameDataBuffer = undefined;\n }\n}\n"],"names":["Pipeline","inputCanvas","outputCanvas","config","videoElement","inputCanvasCtx","timestamp","performInference","frameData","rawImageData","maskImageData","maskResult","frame","maskEntry","_a","needFreshImageData","modelInput","inputImage","resizeImage","performedInference","BlurRenderer","PassthroughRenderer","ReplacementRenderer","WorkerGenerator","_b"],"mappings":"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"}
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "5.5.0";
1
+ export declare const LIB_VERSION = "5.5.1";
@@ -1,4 +1,4 @@
1
- const o = "5.5.0";
1
+ const o = "5.5.1";
2
2
  export {
3
3
  o as LIB_VERSION
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sources":["../../../src/lib/version.ts"],"sourcesContent":["export const LIB_VERSION = '5.5.0';\n"],"names":["LIB_VERSION"],"mappings":"AAAO,MAAMA,IAAc;"}
1
+ {"version":3,"file":"version.js","sources":["../../../src/lib/version.ts"],"sourcesContent":["export const LIB_VERSION = '5.5.1';\n"],"names":["LIB_VERSION"],"mappings":"AAAO,MAAMA,IAAc;"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Cisco Ladon-TS
3
3
  * Copyright (c) Cisco Systems, Inc. All rights reserved.
4
- * Build timestamp: April 16, 2025 at 12:19:28 AM UTC
4
+ * Build timestamp: May 6, 2025 at 06:08:30 PM UTC
5
5
  */
6
6
  (function(){"use strict";var _documentCurrentScript=typeof document<"u"?document.currentScript:null;self.document={baseURI:location.origin};const originalConsoleLog=console.log,originalConsoleWarn=console.warn,originalConsoleError=console.error;console.log=(...e)=>{postMessage({type:"log",message:e.join(" "),severity:"log"}),originalConsoleLog(...e)},console.warn=(...e)=>{postMessage({type:"log",message:e.join(" "),severity:"warn"}),originalConsoleWarn(...e)},console.error=(...e)=>{postMessage({type:"log",message:e.join(" "),severity:"error"}),originalConsoleError(...e)};/*!
7
7
  * ONNX Runtime Web v1.20.1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/ladon-ts",
3
- "version": "5.5.0",
3
+ "version": "5.5.1",
4
4
  "description": "WebexIntelligence computer vision library",
5
5
  "type": "module",
6
6
  "main": "build/module/index.js",