@webex/ladon-ts 5.8.0 → 5.9.0

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.9.0 (2025-07-01)
6
+
7
+
8
+ ### Features
9
+
10
+ * upload background directly to GPU texture ([#74](https://github.com/beyonddunbar/ladon-ts/issues/74)) ([a05b494](https://github.com/beyonddunbar/ladon-ts/commit/a05b4947ae024a430b6006a4a468b5107fd15fb5))
11
+
5
12
  ## 5.8.0 (2025-07-01)
6
13
 
7
14
 
@@ -71,9 +71,9 @@ export declare class ConfigurationBuilder {
71
71
  setBlurSigma(sigma: number): ConfigurationBuilder;
72
72
  /**
73
73
  * Sets the replacement background.
74
- * @param background The background to use for replacement.
74
+ * @param background The background canvas or video element to use for replacement.
75
75
  */
76
- setReplacementBackground(background: HTMLCanvasElement): ConfigurationBuilder;
76
+ setReplacementBackground(background: HTMLCanvasElement | HTMLVideoElement): ConfigurationBuilder;
77
77
  /**
78
78
  * Sets the replacement static property.
79
79
  * @param isStatic Boolean indicating if the replacement is static.
@@ -104,7 +104,7 @@ class a {
104
104
  }
105
105
  /**
106
106
  * Sets the replacement background.
107
- * @param background The background to use for replacement.
107
+ * @param background The background canvas or video element to use for replacement.
108
108
  */
109
109
  setReplacementBackground(e) {
110
110
  if (!this.config.render || this.config.render.type !== "replacement")
@@ -1 +1 @@
1
- {"version":3,"file":"config-builder.js","sources":["../../../src/lib/config-builder.ts"],"sourcesContent":["import rawConfig from '../config.json';\n\nimport {\n AssetUrlResolver,\n BlurConfig,\n BlurStrength,\n Generator,\n InputConfig,\n MaskConfig,\n PassthroughConfig,\n PipelineConfig,\n PreloadConfig,\n Quality,\n RawConfig,\n RenderConfig,\n} from './config-types';\nimport { LIB_VERSION } from './version';\n\n/**\n * Internal mutable versions of the configurations used within the builder.\n */\ninterface MutableSizeConfig {\n height: number;\n width: number;\n}\n\ninterface MutableRenderConfig {\n type: 'blur' | 'passthrough' | 'replacement';\n horizontalMirror?: boolean;\n}\n\ninterface MutableBlurConfig extends MutableRenderConfig {\n type: 'blur';\n kernelSize: number;\n sigma: number;\n}\n\ninterface MutableReplacementConfig extends MutableRenderConfig {\n type: 'replacement';\n background: HTMLCanvasElement;\n static: boolean;\n // TODO: add reposition args for presentation mode\n}\n\ninterface MutableBaseMaskConfig {\n generator: Generator;\n generationIntervalMs: number;\n modelRank: number;\n modelUri: string;\n workerUri: string;\n inputSize?: MutableSizeConfig;\n outputSize?: MutableSizeConfig;\n upscaleSize?: MutableSizeConfig;\n}\n\ninterface MutableMaskConfig extends MutableBaseMaskConfig {\n inputSize: MutableSizeConfig;\n outputSize: MutableSizeConfig;\n upscaleSize: MutableSizeConfig;\n qualityKey?: keyof RawConfig['modelQualities'];\n}\n\ninterface MutablePipelineConfig {\n baseUrl?: string;\n wasmUri?: string;\n executionProviders?: string[];\n render?: MutableBlurConfig | MutableRenderConfig | MutableReplacementConfig;\n input?: MutableSizeConfig;\n mask?: MutableMaskConfig;\n assetUrlResolver?: AssetUrlResolver;\n}\n\n/**\n * A builder class for creating PipelineConfig instances in a flexible and intuitive way.\n */\nexport class ConfigurationBuilder {\n private config: MutablePipelineConfig = {};\n\n constructor(private env: 'int' | 'prod' = 'prod') {}\n\n /**\n * Sets the base URL for the configuration.\n * @param baseUrl The base URL to use.\n */\n public setBaseUrl(baseUrl: string): ConfigurationBuilder {\n // Remove trailing slashes from the base URL\n this.config.baseUrl = baseUrl.replace(/\\/+$/, '');\n return this;\n }\n\n /**\n * Sets the WASM URI for the configuration.\n * @param wasmUri The WASM URI to use.\n */\n public setWasmUri(wasmUri: string): ConfigurationBuilder {\n this.config.wasmUri = wasmUri;\n return this;\n }\n\n /**\n * Sets the asset URL resolver.\n * @param assetUrlResolver The asset URL resolver to use\n * @returns The current ConfigurationBuilder instance.\n */\n public setAssetUrlResolver(assetUrlResolver: AssetUrlResolver): ConfigurationBuilder {\n this.config.assetUrlResolver = assetUrlResolver;\n return this;\n }\n\n /**\n * Sets the execution providers for the ONNX runtime.\n *\n * @param executionProviders The execution providers to use.\n */\n public setExecutionProviders(executionProviders: string[]): ConfigurationBuilder {\n // Allow a single string to be passed as well. This is useful for setting a single provider.\n // This will convert the string to an array for consistency.\n if (typeof executionProviders === 'string') {\n executionProviders = [executionProviders];\n }\n this.config.executionProviders = executionProviders;\n return this;\n }\n\n /**\n * Sets the input size for the configuration.\n * @param height The height of the input.\n * @param width The width of the input.\n */\n public setInputSize(height: number, width: number): ConfigurationBuilder {\n this.config.input = { height, width };\n return this;\n }\n\n /**\n * Sets the input configuration.\n * @param inputConfig The input configuration to use.\n */\n public setInputConfig(inputConfig: InputConfig): ConfigurationBuilder {\n this.config.input = { ...inputConfig };\n return this;\n }\n\n /**\n * Sets the render configuration.\n * @param renderConfig The render configuration to use.\n */\n public setRenderConfig(renderConfig: RenderConfig): ConfigurationBuilder {\n this.config.render = { ...renderConfig } as MutableRenderConfig;\n return this;\n }\n\n /**\n * Sets the render type.\n * @param type The render type ('blur', 'passthrough', 'replacement').\n */\n public setRenderType(type: 'blur' | 'passthrough' | 'replacement'): ConfigurationBuilder {\n if (!this.config.render) {\n this.config.render = { type };\n } else {\n this.config.render.type = type;\n }\n return this;\n }\n\n /**\n * Sets the horizontal mirror property for the render configuration.\n * @param horizontalMirror Boolean indicating if horizontal mirror should be applied.\n */\n public setRenderHorizontalMirror(horizontalMirror: boolean): ConfigurationBuilder {\n if (!this.config.render) {\n throw new Error('Render config must be set before setting horizontal mirror.');\n }\n this.config.render.horizontalMirror = horizontalMirror;\n return this;\n }\n\n /**\n * Sets the blur strength for the render configuration.\n * @param blurStrength The blur strength to use.\n */\n public setBlurStrength(blurStrength: BlurStrength): ConfigurationBuilder {\n const blurConfig = ConfigurationBuilder.getBlurConfig(\n blurStrength,\n this.config.render?.horizontalMirror\n );\n this.config.render = { ...this.config.render, ...blurConfig };\n return this;\n }\n\n /**\n * Sets the blur kernel size.\n * @param kernelSize The kernel size for the blur effect.\n */\n public setBlurKernelSize(kernelSize: number): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'blur') {\n throw new Error('Render config must be of type blur to set blur properties.');\n }\n (this.config.render as MutableBlurConfig).kernelSize = kernelSize;\n return this;\n }\n\n /**\n * Sets the blur sigma value.\n * @param sigma The sigma value for the blur effect.\n */\n public setBlurSigma(sigma: number): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'blur') {\n throw new Error('Render config must be of type blur to set blur properties.');\n }\n (this.config.render as MutableBlurConfig).sigma = sigma;\n return this;\n }\n\n /**\n * Sets the replacement background.\n * @param background The background to use for replacement.\n */\n public setReplacementBackground(background: HTMLCanvasElement): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'replacement') {\n throw new Error(\n 'Render config must be of type replacement to set replacement properties.'\n );\n }\n (this.config.render as MutableReplacementConfig).background = background;\n return this;\n }\n\n /**\n * Sets the replacement static property.\n * @param isStatic Boolean indicating if the replacement is static.\n */\n public setReplacementStatic(isStatic: boolean): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'replacement') {\n throw new Error(\n 'Render config must be of type replacement to set replacement properties.'\n );\n }\n (this.config.render as MutableReplacementConfig).static = isStatic;\n return this;\n }\n\n /**\n * Sets the mask configuration.\n * @param maskConfig The mask configuration to use.\n */\n public setMaskConfig(maskConfig: MaskConfig): ConfigurationBuilder {\n this.config.mask = { ...maskConfig } as MutableMaskConfig;\n return this;\n }\n\n /**\n * Sets the mask generator.\n * @param generator The generator type (most be 'worker'; 'local' is deprecated).\n */\n public setMaskGenerator(generator: Generator): ConfigurationBuilder {\n if (generator !== 'worker') {\n console.warn('[ladon-ts] Mask generator must be \"worker\". \"local\" is deprecated.');\n }\n const mask = this.getMaskConfig();\n mask.generator = generator;\n return this;\n }\n\n /**\n * Sets the mask generation interval in milliseconds.\n * @param intervalMs The generation interval in milliseconds.\n */\n public setMaskGenerationIntervalMs(intervalMs: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.generationIntervalMs = intervalMs;\n return this;\n }\n\n /**\n * Sets the mask model rank.\n * @param modelRank The model rank to use.\n */\n public setMaskModelRank(modelRank: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.modelRank = modelRank;\n return this;\n }\n\n /**\n * Sets the mask model URI.\n * @param modelUri The model URI to use.\n */\n public setMaskModelUri(modelUri: string): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.modelUri = modelUri;\n return this;\n }\n\n /**\n * Sets the mask worker URI.\n * @param workerUri The worker URI to use.\n */\n public setMaskWorkerUri(workerUri: string): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.workerUri = workerUri;\n return this;\n }\n\n /**\n * Sets the mask input size.\n * @param height The height of the mask input.\n * @param width The width of the mask input.\n */\n public setMaskInputSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.inputSize = { height, width };\n return this;\n }\n\n /**\n * Sets the mask output size.\n * @param height The height of the mask output.\n * @param width The width of the mask output.\n */\n public setMaskOutputSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.outputSize = { height, width };\n return this;\n }\n\n /**\n * Sets the mask upscaled size.\n * @param height The height of the upscaled mask.\n * @param width The width of the upscaled mask.\n */\n public setMaskUpscaleSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.upscaleSize = { height, width };\n return this;\n }\n\n /**\n * Sets the quality level and updates mask configurations accordingly.\n * @param quality The desired quality level.\n */\n public setMaskQuality(quality: Quality): ConfigurationBuilder {\n const { modelQualities } = rawConfig;\n\n const mask = this.getMaskConfig();\n const qualityKey = quality.toLowerCase() as keyof RawConfig['modelQualities'];\n const qualityConfig = modelQualities[qualityKey];\n\n if (!qualityConfig) {\n throw new Error(`[ladon-ts] unknown quality option: ${quality}`);\n }\n\n // Store the quality key for dynamic resolution later\n mask.qualityKey = qualityKey;\n\n // Copy other quality-specific properties into the mask config\n Object.assign(mask, qualityConfig);\n\n return this;\n }\n\n /**\n * Builds and returns the PreloadConfig or PipelineConfig object.\n *\n * @param requireInputConfig Whether to require the input configuration to be set before building.\n * Input size is not available at preload so this needs to be optional. The default value is true.\n *\n */\n public build(requireInputConfig = true): PipelineConfig | PreloadConfig {\n const baseUrl = this.resolveBaseUrl();\n const modelUri = this.resolveModelUri();\n const wasmUri = this.resolveWasmUri();\n const workerUri = this.resolveWorkerUri();\n\n const input = this.config.input;\n const render = this.config.render;\n const maskConfig = this.config.mask;\n const executionProviders = this.config.executionProviders;\n const assetUrlResolver = this.config.assetUrlResolver;\n\n if (!maskConfig) {\n throw new Error('Mask configuration must be set before building the configuration.');\n }\n\n const mask: MaskConfig = {\n generator: maskConfig.generator,\n generationIntervalMs: maskConfig.generationIntervalMs,\n modelRank: maskConfig.modelRank,\n inputSize: maskConfig.inputSize,\n outputSize: maskConfig.outputSize,\n upscaleSize: maskConfig.upscaleSize,\n modelUri,\n workerUri,\n };\n\n // Build the preload configuration, which is valid for both preload and pipeline.\n const preloadConfig = {\n assetUrlResolver,\n executionProviders,\n baseUrl,\n wasmUri,\n mask,\n };\n\n if (requireInputConfig) {\n if (!input) {\n throw new Error('Input must be set before building the configuration.');\n }\n\n if (!render) {\n throw new Error('Render must be set before building the configuration.');\n }\n\n // Build the full PipelineConfig\n const pipelineConfig = {\n ...preloadConfig,\n input,\n render,\n } as PipelineConfig;\n\n return pipelineConfig;\n }\n\n return preloadConfig as PreloadConfig;\n }\n\n /**\n * Returns the mask configuration, initializing it if necessary.\n */\n private getMaskConfig(): MutableMaskConfig {\n if (!this.config.mask) {\n this.config.mask = {} as MutableMaskConfig;\n }\n return this.config.mask;\n }\n\n /**\n * Returns the base URL for the configuration.\n */\n public resolveBaseUrl(): string {\n // TODO: Do we want to publish the base URL in the raw config? It seems like the models\n // auth service should be responsible for this, or the user should provide the base url.\n return this.config.baseUrl || rawConfig.baseUrls[this.env];\n }\n\n /**\n * Returns the base URL for the configuration.\n *\n * @returns The base URL for the configuration.\n */\n public resolveModelUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.mask?.modelUri) {\n return this.config.mask.modelUri;\n }\n\n const mask = this.getMaskConfig();\n if (!mask.qualityKey) {\n throw new Error('[ladon-ts] No quality set, cannot infer modelFile.');\n }\n\n return this.resolveTemplate(rawConfig.modelUrlTemplate, {\n BASE_PATH_MODELS: rawConfig.basePaths.models,\n MODEL_VERSION: rawConfig.modelVersion,\n MODEL_FILE: rawConfig.modelQualities[mask.qualityKey].modelFile,\n });\n }\n\n public resolveWasmUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.wasmUri) {\n return this.config.wasmUri;\n }\n\n return this.resolveTemplate(rawConfig.wasmPathTemplate, {\n BASE_PATH_WASM: rawConfig.basePaths.wasm,\n ONNX_VERSION: rawConfig.onnxVersion,\n });\n }\n\n public resolveWorkerUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.mask?.workerUri) {\n return this.config.mask.workerUri;\n }\n\n return this.resolveTemplate(rawConfig.workerUrlTemplate, {\n BASE_PATH_WORKERS: rawConfig.basePaths.workers,\n LIB_VERSION: ConfigurationBuilder.getLibVersion(),\n WORKER_FILE: rawConfig.workerFile,\n });\n }\n\n /**\n * Resolves a template string with the specified values.\n *\n * @param template The template string to resolve.\n * @param values The values to use for resolution.\n * @returns The resolved template string.\n */\n private resolveTemplate(template: string, values: Record<string, string>): string {\n return template.replace(/\\$\\{([A-Z_]+)\\}/g, (_, key) => {\n if (!values[key]) {\n throw new Error(`Missing value for template variable: ${key}`);\n }\n return values[key];\n });\n }\n\n /**\n * Generates a blur configuration based on the specified blur strength.\n * @param blurStrength The desired blur strength.\n * @param horizontalMirror Whether to apply horizontal mirroring.\n */\n public static getBlurConfig(\n blurStrength: BlurStrength,\n horizontalMirror?: boolean\n ): BlurConfig {\n const strengthKey = blurStrength.toLowerCase() as keyof RawConfig['blurStrengths'];\n const blurConfig = rawConfig.blurStrengths[strengthKey];\n\n if (!blurConfig) {\n throw new Error(`[ladon-ts] Unknown blur strength: ${blurStrength}`);\n }\n\n return {\n type: 'blur',\n horizontalMirror,\n ...blurConfig,\n };\n }\n\n public static getPassthroughConfig(horizontalMirror?: boolean): PassthroughConfig {\n return {\n type: 'passthrough',\n horizontalMirror,\n };\n }\n\n /**\n * Returns the library version.\n *\n * @returns The library version.\n */\n public static getLibVersion(): string {\n return LIB_VERSION;\n }\n}\n"],"names":["ConfigurationBuilder","env","baseUrl","wasmUri","assetUrlResolver","executionProviders","height","width","inputConfig","renderConfig","type","horizontalMirror","blurStrength","blurConfig","_a","kernelSize","sigma","background","isStatic","maskConfig","generator","mask","intervalMs","modelRank","modelUri","workerUri","quality","modelQualities","rawConfig","qualityKey","qualityConfig","requireInputConfig","input","render","preloadConfig","template","values","_","key","strengthKey","LIB_VERSION"],"mappings":"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"}
1
+ {"version":3,"file":"config-builder.js","sources":["../../../src/lib/config-builder.ts"],"sourcesContent":["import rawConfig from '../config.json';\n\nimport {\n AssetUrlResolver,\n BlurConfig,\n BlurStrength,\n Generator,\n InputConfig,\n MaskConfig,\n PassthroughConfig,\n PipelineConfig,\n PreloadConfig,\n Quality,\n RawConfig,\n RenderConfig,\n} from './config-types';\nimport { LIB_VERSION } from './version';\n\n/**\n * Internal mutable versions of the configurations used within the builder.\n */\ninterface MutableSizeConfig {\n height: number;\n width: number;\n}\n\ninterface MutableRenderConfig {\n type: 'blur' | 'passthrough' | 'replacement';\n horizontalMirror?: boolean;\n}\n\ninterface MutableBlurConfig extends MutableRenderConfig {\n type: 'blur';\n kernelSize: number;\n sigma: number;\n}\n\ninterface MutableReplacementConfig extends MutableRenderConfig {\n type: 'replacement';\n background: HTMLCanvasElement | HTMLVideoElement;\n static: boolean;\n}\ninterface MutableBaseMaskConfig {\n generator: Generator;\n generationIntervalMs: number;\n modelRank: number;\n modelUri: string;\n workerUri: string;\n inputSize?: MutableSizeConfig;\n outputSize?: MutableSizeConfig;\n upscaleSize?: MutableSizeConfig;\n}\n\ninterface MutableMaskConfig extends MutableBaseMaskConfig {\n inputSize: MutableSizeConfig;\n outputSize: MutableSizeConfig;\n upscaleSize: MutableSizeConfig;\n qualityKey?: keyof RawConfig['modelQualities'];\n}\n\ninterface MutablePipelineConfig {\n baseUrl?: string;\n wasmUri?: string;\n executionProviders?: string[];\n render?: MutableBlurConfig | MutableRenderConfig | MutableReplacementConfig;\n input?: MutableSizeConfig;\n mask?: MutableMaskConfig;\n assetUrlResolver?: AssetUrlResolver;\n}\n\n/**\n * A builder class for creating PipelineConfig instances in a flexible and intuitive way.\n */\nexport class ConfigurationBuilder {\n private config: MutablePipelineConfig = {};\n\n constructor(private env: 'int' | 'prod' = 'prod') {}\n\n /**\n * Sets the base URL for the configuration.\n * @param baseUrl The base URL to use.\n */\n public setBaseUrl(baseUrl: string): ConfigurationBuilder {\n // Remove trailing slashes from the base URL\n this.config.baseUrl = baseUrl.replace(/\\/+$/, '');\n return this;\n }\n\n /**\n * Sets the WASM URI for the configuration.\n * @param wasmUri The WASM URI to use.\n */\n public setWasmUri(wasmUri: string): ConfigurationBuilder {\n this.config.wasmUri = wasmUri;\n return this;\n }\n\n /**\n * Sets the asset URL resolver.\n * @param assetUrlResolver The asset URL resolver to use\n * @returns The current ConfigurationBuilder instance.\n */\n public setAssetUrlResolver(assetUrlResolver: AssetUrlResolver): ConfigurationBuilder {\n this.config.assetUrlResolver = assetUrlResolver;\n return this;\n }\n\n /**\n * Sets the execution providers for the ONNX runtime.\n *\n * @param executionProviders The execution providers to use.\n */\n public setExecutionProviders(executionProviders: string[]): ConfigurationBuilder {\n // Allow a single string to be passed as well. This is useful for setting a single provider.\n // This will convert the string to an array for consistency.\n if (typeof executionProviders === 'string') {\n executionProviders = [executionProviders];\n }\n this.config.executionProviders = executionProviders;\n return this;\n }\n\n /**\n * Sets the input size for the configuration.\n * @param height The height of the input.\n * @param width The width of the input.\n */\n public setInputSize(height: number, width: number): ConfigurationBuilder {\n this.config.input = { height, width };\n return this;\n }\n\n /**\n * Sets the input configuration.\n * @param inputConfig The input configuration to use.\n */\n public setInputConfig(inputConfig: InputConfig): ConfigurationBuilder {\n this.config.input = { ...inputConfig };\n return this;\n }\n\n /**\n * Sets the render configuration.\n * @param renderConfig The render configuration to use.\n */\n public setRenderConfig(renderConfig: RenderConfig): ConfigurationBuilder {\n this.config.render = { ...renderConfig } as MutableRenderConfig;\n return this;\n }\n\n /**\n * Sets the render type.\n * @param type The render type ('blur', 'passthrough', 'replacement').\n */\n public setRenderType(type: 'blur' | 'passthrough' | 'replacement'): ConfigurationBuilder {\n if (!this.config.render) {\n this.config.render = { type };\n } else {\n this.config.render.type = type;\n }\n return this;\n }\n\n /**\n * Sets the horizontal mirror property for the render configuration.\n * @param horizontalMirror Boolean indicating if horizontal mirror should be applied.\n */\n public setRenderHorizontalMirror(horizontalMirror: boolean): ConfigurationBuilder {\n if (!this.config.render) {\n throw new Error('Render config must be set before setting horizontal mirror.');\n }\n this.config.render.horizontalMirror = horizontalMirror;\n return this;\n }\n\n /**\n * Sets the blur strength for the render configuration.\n * @param blurStrength The blur strength to use.\n */\n public setBlurStrength(blurStrength: BlurStrength): ConfigurationBuilder {\n const blurConfig = ConfigurationBuilder.getBlurConfig(\n blurStrength,\n this.config.render?.horizontalMirror\n );\n this.config.render = { ...this.config.render, ...blurConfig };\n return this;\n }\n\n /**\n * Sets the blur kernel size.\n * @param kernelSize The kernel size for the blur effect.\n */\n public setBlurKernelSize(kernelSize: number): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'blur') {\n throw new Error('Render config must be of type blur to set blur properties.');\n }\n (this.config.render as MutableBlurConfig).kernelSize = kernelSize;\n return this;\n }\n\n /**\n * Sets the blur sigma value.\n * @param sigma The sigma value for the blur effect.\n */\n public setBlurSigma(sigma: number): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'blur') {\n throw new Error('Render config must be of type blur to set blur properties.');\n }\n (this.config.render as MutableBlurConfig).sigma = sigma;\n return this;\n }\n\n /**\n * Sets the replacement background.\n * @param background The background canvas or video element to use for replacement.\n */\n public setReplacementBackground(\n background: HTMLCanvasElement | HTMLVideoElement\n ): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'replacement') {\n throw new Error(\n 'Render config must be of type replacement to set replacement properties.'\n );\n }\n (this.config.render as MutableReplacementConfig).background = background;\n return this;\n }\n\n /**\n * Sets the replacement static property.\n * @param isStatic Boolean indicating if the replacement is static.\n */\n public setReplacementStatic(isStatic: boolean): ConfigurationBuilder {\n if (!this.config.render || this.config.render.type !== 'replacement') {\n throw new Error(\n 'Render config must be of type replacement to set replacement properties.'\n );\n }\n (this.config.render as MutableReplacementConfig).static = isStatic;\n return this;\n }\n\n /**\n * Sets the mask configuration.\n * @param maskConfig The mask configuration to use.\n */\n public setMaskConfig(maskConfig: MaskConfig): ConfigurationBuilder {\n this.config.mask = { ...maskConfig } as MutableMaskConfig;\n return this;\n }\n\n /**\n * Sets the mask generator.\n * @param generator The generator type (most be 'worker'; 'local' is deprecated).\n */\n public setMaskGenerator(generator: Generator): ConfigurationBuilder {\n if (generator !== 'worker') {\n console.warn('[ladon-ts] Mask generator must be \"worker\". \"local\" is deprecated.');\n }\n const mask = this.getMaskConfig();\n mask.generator = generator;\n return this;\n }\n\n /**\n * Sets the mask generation interval in milliseconds.\n * @param intervalMs The generation interval in milliseconds.\n */\n public setMaskGenerationIntervalMs(intervalMs: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.generationIntervalMs = intervalMs;\n return this;\n }\n\n /**\n * Sets the mask model rank.\n * @param modelRank The model rank to use.\n */\n public setMaskModelRank(modelRank: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.modelRank = modelRank;\n return this;\n }\n\n /**\n * Sets the mask model URI.\n * @param modelUri The model URI to use.\n */\n public setMaskModelUri(modelUri: string): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.modelUri = modelUri;\n return this;\n }\n\n /**\n * Sets the mask worker URI.\n * @param workerUri The worker URI to use.\n */\n public setMaskWorkerUri(workerUri: string): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.workerUri = workerUri;\n return this;\n }\n\n /**\n * Sets the mask input size.\n * @param height The height of the mask input.\n * @param width The width of the mask input.\n */\n public setMaskInputSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.inputSize = { height, width };\n return this;\n }\n\n /**\n * Sets the mask output size.\n * @param height The height of the mask output.\n * @param width The width of the mask output.\n */\n public setMaskOutputSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.outputSize = { height, width };\n return this;\n }\n\n /**\n * Sets the mask upscaled size.\n * @param height The height of the upscaled mask.\n * @param width The width of the upscaled mask.\n */\n public setMaskUpscaleSize(height: number, width: number): ConfigurationBuilder {\n const mask = this.getMaskConfig();\n mask.upscaleSize = { height, width };\n return this;\n }\n\n /**\n * Sets the quality level and updates mask configurations accordingly.\n * @param quality The desired quality level.\n */\n public setMaskQuality(quality: Quality): ConfigurationBuilder {\n const { modelQualities } = rawConfig;\n\n const mask = this.getMaskConfig();\n const qualityKey = quality.toLowerCase() as keyof RawConfig['modelQualities'];\n const qualityConfig = modelQualities[qualityKey];\n\n if (!qualityConfig) {\n throw new Error(`[ladon-ts] unknown quality option: ${quality}`);\n }\n\n // Store the quality key for dynamic resolution later\n mask.qualityKey = qualityKey;\n\n // Copy other quality-specific properties into the mask config\n Object.assign(mask, qualityConfig);\n\n return this;\n }\n\n /**\n * Builds and returns the PreloadConfig or PipelineConfig object.\n *\n * @param requireInputConfig Whether to require the input configuration to be set before building.\n * Input size is not available at preload so this needs to be optional. The default value is true.\n *\n */\n public build(requireInputConfig = true): PipelineConfig | PreloadConfig {\n const baseUrl = this.resolveBaseUrl();\n const modelUri = this.resolveModelUri();\n const wasmUri = this.resolveWasmUri();\n const workerUri = this.resolveWorkerUri();\n\n const input = this.config.input;\n const render = this.config.render;\n const maskConfig = this.config.mask;\n const executionProviders = this.config.executionProviders;\n const assetUrlResolver = this.config.assetUrlResolver;\n\n if (!maskConfig) {\n throw new Error('Mask configuration must be set before building the configuration.');\n }\n\n const mask: MaskConfig = {\n generator: maskConfig.generator,\n generationIntervalMs: maskConfig.generationIntervalMs,\n modelRank: maskConfig.modelRank,\n inputSize: maskConfig.inputSize,\n outputSize: maskConfig.outputSize,\n upscaleSize: maskConfig.upscaleSize,\n modelUri,\n workerUri,\n };\n\n // Build the preload configuration, which is valid for both preload and pipeline.\n const preloadConfig = {\n assetUrlResolver,\n executionProviders,\n baseUrl,\n wasmUri,\n mask,\n };\n\n if (requireInputConfig) {\n if (!input) {\n throw new Error('Input must be set before building the configuration.');\n }\n\n if (!render) {\n throw new Error('Render must be set before building the configuration.');\n }\n\n // Build the full PipelineConfig\n const pipelineConfig = {\n ...preloadConfig,\n input,\n render,\n } as PipelineConfig;\n\n return pipelineConfig;\n }\n\n return preloadConfig as PreloadConfig;\n }\n\n /**\n * Returns the mask configuration, initializing it if necessary.\n */\n private getMaskConfig(): MutableMaskConfig {\n if (!this.config.mask) {\n this.config.mask = {} as MutableMaskConfig;\n }\n return this.config.mask;\n }\n\n /**\n * Returns the base URL for the configuration.\n */\n public resolveBaseUrl(): string {\n // TODO: Do we want to publish the base URL in the raw config? It seems like the models\n // auth service should be responsible for this, or the user should provide the base url.\n return this.config.baseUrl || rawConfig.baseUrls[this.env];\n }\n\n /**\n * Returns the base URL for the configuration.\n *\n * @returns The base URL for the configuration.\n */\n public resolveModelUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.mask?.modelUri) {\n return this.config.mask.modelUri;\n }\n\n const mask = this.getMaskConfig();\n if (!mask.qualityKey) {\n throw new Error('[ladon-ts] No quality set, cannot infer modelFile.');\n }\n\n return this.resolveTemplate(rawConfig.modelUrlTemplate, {\n BASE_PATH_MODELS: rawConfig.basePaths.models,\n MODEL_VERSION: rawConfig.modelVersion,\n MODEL_FILE: rawConfig.modelQualities[mask.qualityKey].modelFile,\n });\n }\n\n public resolveWasmUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.wasmUri) {\n return this.config.wasmUri;\n }\n\n return this.resolveTemplate(rawConfig.wasmPathTemplate, {\n BASE_PATH_WASM: rawConfig.basePaths.wasm,\n ONNX_VERSION: rawConfig.onnxVersion,\n });\n }\n\n public resolveWorkerUri(): string {\n // First check if the property is explicitly set in the config, then fallback to rawConfig\n if (this.config.mask?.workerUri) {\n return this.config.mask.workerUri;\n }\n\n return this.resolveTemplate(rawConfig.workerUrlTemplate, {\n BASE_PATH_WORKERS: rawConfig.basePaths.workers,\n LIB_VERSION: ConfigurationBuilder.getLibVersion(),\n WORKER_FILE: rawConfig.workerFile,\n });\n }\n\n /**\n * Resolves a template string with the specified values.\n *\n * @param template The template string to resolve.\n * @param values The values to use for resolution.\n * @returns The resolved template string.\n */\n private resolveTemplate(template: string, values: Record<string, string>): string {\n return template.replace(/\\$\\{([A-Z_]+)\\}/g, (_, key) => {\n if (!values[key]) {\n throw new Error(`Missing value for template variable: ${key}`);\n }\n return values[key];\n });\n }\n\n /**\n * Generates a blur configuration based on the specified blur strength.\n * @param blurStrength The desired blur strength.\n * @param horizontalMirror Whether to apply horizontal mirroring.\n */\n public static getBlurConfig(\n blurStrength: BlurStrength,\n horizontalMirror?: boolean\n ): BlurConfig {\n const strengthKey = blurStrength.toLowerCase() as keyof RawConfig['blurStrengths'];\n const blurConfig = rawConfig.blurStrengths[strengthKey];\n\n if (!blurConfig) {\n throw new Error(`[ladon-ts] Unknown blur strength: ${blurStrength}`);\n }\n\n return {\n type: 'blur',\n horizontalMirror,\n ...blurConfig,\n };\n }\n\n public static getPassthroughConfig(horizontalMirror?: boolean): PassthroughConfig {\n return {\n type: 'passthrough',\n horizontalMirror,\n };\n }\n\n /**\n * Returns the library version.\n *\n * @returns The library version.\n */\n public static getLibVersion(): string {\n return LIB_VERSION;\n }\n}\n"],"names":["ConfigurationBuilder","env","baseUrl","wasmUri","assetUrlResolver","executionProviders","height","width","inputConfig","renderConfig","type","horizontalMirror","blurStrength","blurConfig","_a","kernelSize","sigma","background","isStatic","maskConfig","generator","mask","intervalMs","modelRank","modelUri","workerUri","quality","modelQualities","rawConfig","qualityKey","qualityConfig","requireInputConfig","input","render","preloadConfig","template","values","_","key","strengthKey","LIB_VERSION"],"mappings":"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"}
@@ -41,9 +41,10 @@ export interface BlurConfig extends RenderConfig {
41
41
  readonly sigma: number;
42
42
  }
43
43
  export interface ReplacementConfig extends RenderConfig {
44
+ readonly background: HTMLCanvasElement | HTMLVideoElement;
44
45
  readonly type: 'replacement';
45
- readonly background: HTMLCanvasElement;
46
46
  readonly static: boolean;
47
+ readonly horizontalMirror?: boolean;
47
48
  }
48
49
  export interface PassthroughConfig extends RenderConfig {
49
50
  readonly type: 'passthrough';
@@ -1 +1 @@
1
- {"version":3,"file":"config-types.js","sources":["../../../src/lib/config-types.ts"],"sourcesContent":["export enum Quality {\n TINY = 'TINY',\n LOW = 'LOW',\n MEDIUM = 'MEDIUM',\n HIGH = 'HIGH',\n ULTRA = 'ULTRA',\n}\n\nexport enum BlurStrength {\n WEAK = 'WEAK',\n MODERATE = 'MODERATE',\n STRONG = 'STRONG',\n STRONGER = 'STRONGER',\n STRONGEST = 'STRONGEST',\n}\n\nexport type ResolutionConfig = {\n readonly height: number;\n readonly width: number;\n};\n\nexport interface SizeConfig {\n readonly inputSize: ResolutionConfig;\n readonly outputSize: ResolutionConfig;\n readonly upscaleSize: ResolutionConfig;\n}\n\nexport interface ModelQualityConfig {\n readonly modelFile: string;\n readonly modelRank: number;\n readonly generationIntervalMs: number;\n readonly inputSize: ResolutionConfig;\n readonly outputSize: ResolutionConfig;\n readonly upscaleSize: ResolutionConfig;\n}\n\nexport type InputConfig = ResolutionConfig;\n\nexport type AssetUrlResolver = (assetUri: string, config: PreloadConfig) => Promise<string>;\n\nexport interface RenderConfig {\n readonly type: 'blur' | 'passthrough' | 'replacement';\n readonly horizontalMirror?: boolean;\n}\n\nexport interface BlurConfig extends RenderConfig {\n readonly type: 'blur';\n readonly kernelSize: number;\n readonly sigma: number;\n}\n\nexport interface ReplacementConfig extends RenderConfig {\n readonly type: 'replacement';\n readonly background: HTMLCanvasElement;\n readonly static: boolean;\n // TODO: add reposition args for presentation mode\n}\n\nexport interface PassthroughConfig extends RenderConfig {\n readonly type: 'passthrough';\n}\n\nexport type Generator = 'worker';\n\nexport type BaseMaskConfig = {\n readonly generator: Generator;\n readonly generationIntervalMs: number;\n readonly modelRank: number;\n readonly modelUri: string;\n readonly workerUri: string;\n // These are optional because the input and output sizes are not known when preloading the model.\n // However, the sizes are needed when creating the pipeline to match the models seize requirements.\n readonly inputSize?: ResolutionConfig;\n readonly outputSize?: ResolutionConfig;\n readonly upscaleSize?: ResolutionConfig;\n};\n\nexport type MaskConfig = BaseMaskConfig & SizeConfig;\n\nexport type PreloadConfig = {\n readonly baseUrl?: string;\n readonly wasmUri: string;\n readonly mask: BaseMaskConfig;\n readonly executionProviders?: string[];\n readonly assetUrlResolver?: AssetUrlResolver;\n};\n\nexport type WorkerConfig = Omit<PreloadConfig, 'assetUrlResolver'>;\n\nexport type PipelineConfig = PreloadConfig & {\n readonly render: BlurConfig | RenderConfig | ReplacementConfig;\n readonly input: InputConfig;\n readonly mask: MaskConfig;\n};\n\nexport interface RawConfig {\n readonly baseUrls: {\n readonly int: string;\n readonly prod: string;\n };\n readonly basePaths: {\n readonly models: string;\n readonly wasm: string;\n readonly workers: string;\n };\n readonly blurStrengths: {\n readonly [key in Lowercase<BlurStrength>]: {\n readonly kernelSize: number;\n readonly sigma: number;\n };\n };\n readonly modelQualities: {\n readonly [key in Lowercase<Quality>]: ModelQualityConfig;\n };\n readonly onnxVersion: string;\n readonly modelVersion: string;\n readonly workerFile: string;\n readonly modelUrlTemplate: string;\n readonly wasmPathTemplate: string;\n readonly workerUrlTemplate: string;\n}\n"],"names":["Quality","BlurStrength"],"mappings":"AAAY,IAAAA,sBAAAA,OACRA,EAAA,OAAO,QACPA,EAAA,MAAM,OACNA,EAAA,SAAS,UACTA,EAAA,OAAO,QACPA,EAAA,QAAQ,SALAA,IAAAA,KAAA,CAAA,CAAA,GAQAC,sBAAAA,OACRA,EAAA,OAAO,QACPA,EAAA,WAAW,YACXA,EAAA,SAAS,UACTA,EAAA,WAAW,YACXA,EAAA,YAAY,aALJA,IAAAA,KAAA,CAAA,CAAA;"}
1
+ {"version":3,"file":"config-types.js","sources":["../../../src/lib/config-types.ts"],"sourcesContent":["export enum Quality {\n TINY = 'TINY',\n LOW = 'LOW',\n MEDIUM = 'MEDIUM',\n HIGH = 'HIGH',\n ULTRA = 'ULTRA',\n}\n\nexport enum BlurStrength {\n WEAK = 'WEAK',\n MODERATE = 'MODERATE',\n STRONG = 'STRONG',\n STRONGER = 'STRONGER',\n STRONGEST = 'STRONGEST',\n}\n\nexport type ResolutionConfig = {\n readonly height: number;\n readonly width: number;\n};\n\nexport interface SizeConfig {\n readonly inputSize: ResolutionConfig;\n readonly outputSize: ResolutionConfig;\n readonly upscaleSize: ResolutionConfig;\n}\n\nexport interface ModelQualityConfig {\n readonly modelFile: string;\n readonly modelRank: number;\n readonly generationIntervalMs: number;\n readonly inputSize: ResolutionConfig;\n readonly outputSize: ResolutionConfig;\n readonly upscaleSize: ResolutionConfig;\n}\n\nexport type InputConfig = ResolutionConfig;\n\nexport type AssetUrlResolver = (assetUri: string, config: PreloadConfig) => Promise<string>;\n\nexport interface RenderConfig {\n readonly type: 'blur' | 'passthrough' | 'replacement';\n readonly horizontalMirror?: boolean;\n}\n\nexport interface BlurConfig extends RenderConfig {\n readonly type: 'blur';\n readonly kernelSize: number;\n readonly sigma: number;\n}\n\nexport interface ReplacementConfig extends RenderConfig {\n readonly background: HTMLCanvasElement | HTMLVideoElement;\n readonly type: 'replacement';\n readonly static: boolean;\n readonly horizontalMirror?: boolean;\n}\n\nexport interface PassthroughConfig extends RenderConfig {\n readonly type: 'passthrough';\n}\n\nexport type Generator = 'worker';\n\nexport type BaseMaskConfig = {\n readonly generator: Generator;\n readonly generationIntervalMs: number;\n readonly modelRank: number;\n readonly modelUri: string;\n readonly workerUri: string;\n // These are optional because the input and output sizes are not known when preloading the model.\n // However, the sizes are needed when creating the pipeline to match the models seize requirements.\n readonly inputSize?: ResolutionConfig;\n readonly outputSize?: ResolutionConfig;\n readonly upscaleSize?: ResolutionConfig;\n};\n\nexport type MaskConfig = BaseMaskConfig & SizeConfig;\n\nexport type PreloadConfig = {\n readonly baseUrl?: string;\n readonly wasmUri: string;\n readonly mask: BaseMaskConfig;\n readonly executionProviders?: string[];\n readonly assetUrlResolver?: AssetUrlResolver;\n};\n\nexport type WorkerConfig = Omit<PreloadConfig, 'assetUrlResolver'>;\n\nexport type PipelineConfig = PreloadConfig & {\n readonly render: BlurConfig | RenderConfig | ReplacementConfig;\n readonly input: InputConfig;\n readonly mask: MaskConfig;\n};\n\nexport interface RawConfig {\n readonly baseUrls: {\n readonly int: string;\n readonly prod: string;\n };\n readonly basePaths: {\n readonly models: string;\n readonly wasm: string;\n readonly workers: string;\n };\n readonly blurStrengths: {\n readonly [key in Lowercase<BlurStrength>]: {\n readonly kernelSize: number;\n readonly sigma: number;\n };\n };\n readonly modelQualities: {\n readonly [key in Lowercase<Quality>]: ModelQualityConfig;\n };\n readonly onnxVersion: string;\n readonly modelVersion: string;\n readonly workerFile: string;\n readonly modelUrlTemplate: string;\n readonly wasmPathTemplate: string;\n readonly workerUrlTemplate: string;\n}\n"],"names":["Quality","BlurStrength"],"mappings":"AAAY,IAAAA,sBAAAA,OACRA,EAAA,OAAO,QACPA,EAAA,MAAM,OACNA,EAAA,SAAS,UACTA,EAAA,OAAO,QACPA,EAAA,QAAQ,SALAA,IAAAA,KAAA,CAAA,CAAA,GAQAC,sBAAAA,OACRA,EAAA,OAAO,QACPA,EAAA,WAAW,YACXA,EAAA,SAAS,UACTA,EAAA,WAAW,YACXA,EAAA,YAAY,aALJA,IAAAA,KAAA,CAAA,CAAA;"}
@@ -29,6 +29,6 @@ export interface MaskGenerator {
29
29
  getLadonOutputForTimestamp(timestamp: number): Promise<LadonOutput>;
30
30
  load(): Promise<void>;
31
31
  isLoaded(): boolean;
32
- postRender(input: Uint8ClampedArray, timestamp: number): Promise<void>;
32
+ process(input: Uint8ClampedArray, timestamp: number): Promise<void>;
33
33
  destroy(): Promise<void>;
34
34
  }
@@ -1,64 +1,109 @@
1
1
  import { PipelineConfig } from './config-types';
2
+ import { FrameData } from './generator';
2
3
  import { IFrameInferenceResult, IPipeline } from './pipeline-types';
4
+ /**
5
+ * Core pipeline implementation for processing video frames with ML inference and rendering.
6
+ * Handles frame processing, mask generation, and output rendering with proper timing controls.
7
+ */
3
8
  export declare class Pipeline implements IPipeline {
4
9
  private inputCanvas;
5
10
  private outputCanvas;
6
11
  readonly config: PipelineConfig;
7
- private readonly videoElement?;
12
+ private readonly inputVideoElement;
13
+ /** The mask generator responsible for ML inference. */
8
14
  private generator?;
15
+ /** The renderer responsible for compositing the final output. */
9
16
  private renderer?;
17
+ /** Flag indicating whether the pipeline has been fully loaded and initialized. */
10
18
  private loaded;
11
- private inputCanvasCtx;
19
+ /** 2D rendering context for the input canvas used for frame processing. */
20
+ private inputCanvasContext;
21
+ /** The most recent mask result from ML inference, used when skipping inference. */
12
22
  private lastMaskResult?;
13
- private frameDataBuffer?;
14
- constructor(inputCanvas: HTMLCanvasElement, outputCanvas: HTMLCanvasElement, config: PipelineConfig, videoElement?: HTMLVideoElement | undefined);
23
+ /** Flag indicating whether a frame is currently being processed. */
24
+ private isProcessingFrame;
25
+ /** Promise for the currently pending frame processing operation. */
26
+ private pendingFramePromise;
15
27
  /**
16
- * Processes a single frame and returns the inference result.
17
- * This method handles the frame data, performs inference if needed, and renders the output.
28
+ * Create a new pipeline instance.
18
29
  *
19
- * @param timestamp - The timestamp of the frame.
20
- * @param performInference - Flag to perform mask inference.
21
- * @param frameData - Optional frame data to process.
22
- * @returns The result of the frame processing.
23
- * @throws If the pipeline (generator or renderer) is not loaded.
30
+ * @param inputCanvas - Canvas element for input frame processing.
31
+ * @param outputCanvas - Canvas element where the final rendered output will be displayed.
32
+ * @param config - Pipeline configuration containing processing and rendering settings.
33
+ * @param inputVideoElement - Video element serving as the input source.
34
+ * @throws Error if the input canvas 2D context cannot be obtained.
24
35
  */
25
- onFrame(timestamp: number, performInference?: boolean): Promise<IFrameInferenceResult>;
36
+ constructor(inputCanvas: HTMLCanvasElement, outputCanvas: HTMLCanvasElement, config: PipelineConfig, inputVideoElement: HTMLVideoElement);
26
37
  /**
27
- * Gets the raw image data from the input canvas context.
38
+ * Process a single frame and return the inference result.
39
+ * This method handles frame data, performs inference if needed, and renders the output.
40
+ * Includes frame processing serialization to prevent overlapping operations.
28
41
  *
29
- * @param needFreshImageData - Flag to indicate if fresh image data is needed.
42
+ * @param timestamp - The timestamp of the frame in milliseconds.
43
+ * @param performInference - Whether to perform mask inference or reuse the last result.
44
+ * @param frameData - Optional frame data to process instead of capturing from input.
45
+ * @returns Promise resolving to the frame processing result with timing statistics.
46
+ * @throws Error if the pipeline (generator or renderer) is not loaded.
47
+ */
48
+ onFrame(timestamp: number, performInference?: boolean, frameData?: FrameData): Promise<IFrameInferenceResult>;
49
+ /**
50
+ * Internal frame processing implementation.
51
+ * Handles the actual frame processing logic including timing measurements.
52
+ *
53
+ * @param timestamp - The timestamp of the frame in milliseconds.
54
+ * @param performInference - Whether to perform mask inference or reuse the last result.
55
+ * @param frameData - Optional frame data to process instead of capturing from input.
56
+ * @returns Promise resolving to the frame processing result with timing statistics.
57
+ * @throws Error if the pipeline (generator or renderer) is not loaded.
58
+ */
59
+ private processFrameInternal;
60
+ /**
61
+ * Get the raw image data from the input canvas context.
30
62
  *
31
- * @returns The raw image data.
63
+ * @returns The frame data as a Uint8ClampedArray.
32
64
  */
33
65
  private getInputFrameData;
34
66
  /**
35
- * Resizes the image data if the model expects a fixed size input.
67
+ * Resize the image data if the model expects a different input size.
68
+ * Handles scaling between input dimensions and model requirements.
36
69
  *
37
- * @param {Uint8ClampedArray} rawImageData - The raw image data.
38
- * @returns {Uint8ClampedArray} - The processed mask image data.
70
+ * @param rawImageData - The raw image data to potentially resize.
71
+ * @returns The processed mask image data, resized if necessary.
39
72
  */
40
73
  private getMaskImageData;
41
74
  /**
42
- * Creates the inference result object.
75
+ * Create the inference result object with appropriate data.
76
+ * Handles both successful inference results and fallback cases.
43
77
  *
44
- * @param timestamp - The timestamp of the frame.
45
- * @param performedInference - Indicates if the inference was performed.
46
- * @returns The result object containing inference details.
78
+ * @param timestamp - The timestamp of the frame in milliseconds.
79
+ * @param performedInference - Whether inference was actually performed for this frame.
80
+ * @returns The inference result object containing mask data and metadata.
47
81
  */
48
82
  private createInferenceResult;
49
83
  /**
50
- * Checks if the pipeline is loaded.
84
+ * Check if the pipeline is fully loaded and ready for processing.
51
85
  *
52
- * @returns True if the pipeline is loaded, false otherwise.
86
+ * @returns True if the pipeline is loaded and ready, false otherwise.
53
87
  */
54
88
  isLoaded(): boolean;
55
89
  /**
56
- * Loads the pipeline components such as the generator and renderer.
90
+ * Load and initialize the pipeline components.
91
+ * Creates the appropriate renderer and generator based on configuration.
92
+ *
93
+ * @returns Promise that resolves when all components are loaded and ready.
94
+ * @throws Error if an unsupported renderer type is specified in the configuration.
57
95
  */
58
96
  load(): Promise<void>;
97
+ /**
98
+ * Reset the pipeline state by clearing cached mask results.
99
+ * Useful when switching between different processing modes or sources.
100
+ */
59
101
  reset(): void;
60
102
  /**
61
- * Destroys the pipeline and cleans up resources.
103
+ * Destroy the pipeline and clean up all resources.
104
+ * Properly disposes of the renderer and generator to prevent memory leaks.
105
+ *
106
+ * @returns Promise that resolves when cleanup is complete.
62
107
  */
63
108
  destroy(): Promise<void>;
64
109
  }
@@ -1,92 +1,122 @@
1
- import { WorkerGenerator as w } from "./worker-generator.js";
2
- import { BlurRenderer as k } from "./renderer/blur-renderer.js";
3
- import { PassthroughRenderer as R } from "./renderer/passthrough-renderer.js";
4
- import { ReplacementRenderer as v } from "./renderer/replacement-renderer.js";
5
- import { resizeImage as C } from "./util.js";
6
- class A {
7
- constructor(t, e, a, s) {
8
- this.inputCanvas = t, this.outputCanvas = e, this.config = a, this.videoElement = s, this.loaded = !1;
1
+ import { WorkerGenerator as g } from "./worker-generator.js";
2
+ import { BlurRenderer as f } from "./renderer/blur-renderer.js";
3
+ import { PassthroughRenderer as w } from "./renderer/passthrough-renderer.js";
4
+ import { ReplacementRenderer as k } from "./renderer/replacement-renderer.js";
5
+ import { resizeImage as F } from "./util.js";
6
+ class M {
7
+ /**
8
+ * Create a new pipeline instance.
9
+ *
10
+ * @param inputCanvas - Canvas element for input frame processing.
11
+ * @param outputCanvas - Canvas element where the final rendered output will be displayed.
12
+ * @param config - Pipeline configuration containing processing and rendering settings.
13
+ * @param inputVideoElement - Video element serving as the input source.
14
+ * @throws Error if the input canvas 2D context cannot be obtained.
15
+ */
16
+ constructor(t, e, s, n) {
17
+ this.inputCanvas = t, this.outputCanvas = e, this.config = s, this.inputVideoElement = n, this.loaded = !1, this.isProcessingFrame = !1, this.pendingFramePromise = null;
9
18
  const r = this.inputCanvas.getContext("2d", {
10
19
  alpha: !1,
11
20
  willReadFrequently: !0
12
21
  });
13
22
  if (!r)
14
23
  throw new Error("[ladon-ts] Error getting input context 2d");
15
- this.inputCanvasCtx = r;
24
+ this.inputCanvasContext = r;
25
+ }
26
+ /**
27
+ * Process a single frame and return the inference result.
28
+ * This method handles frame data, performs inference if needed, and renders the output.
29
+ * Includes frame processing serialization to prevent overlapping operations.
30
+ *
31
+ * @param timestamp - The timestamp of the frame in milliseconds.
32
+ * @param performInference - Whether to perform mask inference or reuse the last result.
33
+ * @param frameData - Optional frame data to process instead of capturing from input.
34
+ * @returns Promise resolving to the frame processing result with timing statistics.
35
+ * @throws Error if the pipeline (generator or renderer) is not loaded.
36
+ */
37
+ async onFrame(t, e = !0, s) {
38
+ this.isProcessingFrame && this.pendingFramePromise && await this.pendingFramePromise, this.isProcessingFrame = !0;
39
+ try {
40
+ return this.pendingFramePromise = this.processFrameInternal(
41
+ t,
42
+ e,
43
+ s
44
+ ), await this.pendingFramePromise;
45
+ } finally {
46
+ this.isProcessingFrame = !1, this.pendingFramePromise = null;
47
+ }
16
48
  }
17
49
  /**
18
- * Processes a single frame and returns the inference result.
19
- * This method handles the frame data, performs inference if needed, and renders the output.
50
+ * Internal frame processing implementation.
51
+ * Handles the actual frame processing logic including timing measurements.
20
52
  *
21
- * @param timestamp - The timestamp of the frame.
22
- * @param performInference - Flag to perform mask inference.
23
- * @param frameData - Optional frame data to process.
24
- * @returns The result of the frame processing.
25
- * @throws If the pipeline (generator or renderer) is not loaded.
53
+ * @param timestamp - The timestamp of the frame in milliseconds.
54
+ * @param performInference - Whether to perform mask inference or reuse the last result.
55
+ * @param frameData - Optional frame data to process instead of capturing from input.
56
+ * @returns Promise resolving to the frame processing result with timing statistics.
57
+ * @throws Error if the pipeline (generator or renderer) is not loaded.
26
58
  */
27
- async onFrame(t, e = !0) {
28
- const a = performance.now();
59
+ async processFrameInternal(t, e = !0, s) {
60
+ const n = performance.now();
29
61
  if (!this.generator || !this.renderer)
30
62
  throw new Error("[ladon-ts] Pipeline is not loaded.");
31
- const s = performance.now(), r = this.getInputFrameData(e);
32
- let n;
33
- r instanceof Uint8ClampedArray ? ((!this.frameDataBuffer || this.frameDataBuffer.length !== r.length) && (this.frameDataBuffer = new Uint8ClampedArray(r.length)), this.frameDataBuffer.set(r), n = this.frameDataBuffer) : n = r;
34
- const d = performance.now() - s;
35
- let i = 0;
63
+ let r = 0, a = 0;
36
64
  if (e || !this.lastMaskResult) {
37
- const m = performance.now(), p = r, g = this.getMaskImageData(p);
38
- await this.generator.postRender(g, t), this.lastMaskResult = await this.generator.getLadonOutputForTimestamp(t), i = performance.now() - m;
65
+ const c = performance.now();
66
+ s ?? (s = this.getInputFrameData()), r = performance.now() - c;
67
+ const m = performance.now(), u = s, p = this.getMaskImageData(u);
68
+ await this.generator.process(p, t), this.lastMaskResult = await this.generator.getLadonOutputForTimestamp(t), a = performance.now() - m;
39
69
  }
40
- const u = performance.now(), l = this.videoElement || n;
41
- await this.renderer.render(l, this.lastMaskResult);
42
- const f = performance.now() - u, o = performance.now(), c = o - a, h = this.createInferenceResult(t, e);
43
- return h.stats = {
44
- totalFrameTime: c,
45
- modelInferenceTime: i,
46
- preprocessingTime: d,
47
- postprocessingTime: f,
48
- frameStartTime: a,
49
- frameEndTime: o,
70
+ const h = performance.now();
71
+ await this.renderer.render(this.inputVideoElement, this.lastMaskResult);
72
+ const d = performance.now() - h, i = performance.now(), l = i - n, o = this.createInferenceResult(t, e);
73
+ return o.stats = {
74
+ totalFrameTime: l,
75
+ modelInferenceTime: a,
76
+ preprocessingTime: r,
77
+ postprocessingTime: d,
78
+ frameStartTime: n,
79
+ frameEndTime: i,
50
80
  inferenceSkipped: !e
51
- }, h;
81
+ }, o;
52
82
  }
53
83
  /**
54
- * Gets the raw image data from the input canvas context.
84
+ * Get the raw image data from the input canvas context.
55
85
  *
56
- * @param needFreshImageData - Flag to indicate if fresh image data is needed.
57
- *
58
- * @returns The raw image data.
86
+ * @returns The frame data as a Uint8ClampedArray.
59
87
  */
60
- getInputFrameData(t) {
61
- return t || !this.videoElement ? this.inputCanvasCtx.getImageData(
88
+ getInputFrameData() {
89
+ return this.inputCanvasContext.getImageData(
62
90
  0,
63
91
  0,
64
92
  this.config.input.width,
65
93
  this.config.input.height
66
- ).data : this.videoElement;
94
+ ).data;
67
95
  }
68
96
  /**
69
- * Resizes the image data if the model expects a fixed size input.
97
+ * Resize the image data if the model expects a different input size.
98
+ * Handles scaling between input dimensions and model requirements.
70
99
  *
71
- * @param {Uint8ClampedArray} rawImageData - The raw image data.
72
- * @returns {Uint8ClampedArray} - The processed mask image data.
100
+ * @param rawImageData - The raw image data to potentially resize.
101
+ * @returns The processed mask image data, resized if necessary.
73
102
  */
74
103
  getMaskImageData(t) {
75
- const e = this.config.mask.inputSize, a = this.config.input;
76
- return e.width === a.width && e.height === a.height ? t : C(
104
+ const e = this.config.mask.inputSize, s = this.config.input;
105
+ return e.width === s.width && e.height === s.height ? t : F(
77
106
  t,
78
- a.width,
79
- a.height,
107
+ s.width,
108
+ s.height,
80
109
  e.width,
81
110
  e.height
82
111
  );
83
112
  }
84
113
  /**
85
- * Creates the inference result object.
114
+ * Create the inference result object with appropriate data.
115
+ * Handles both successful inference results and fallback cases.
86
116
  *
87
- * @param timestamp - The timestamp of the frame.
88
- * @param performedInference - Indicates if the inference was performed.
89
- * @returns The result object containing inference details.
117
+ * @param timestamp - The timestamp of the frame in milliseconds.
118
+ * @param performedInference - Whether inference was actually performed for this frame.
119
+ * @returns The inference result object containing mask data and metadata.
90
120
  */
91
121
  createInferenceResult(t, e) {
92
122
  return this.lastMaskResult ? {
@@ -106,44 +136,55 @@ class A {
106
136
  };
107
137
  }
108
138
  /**
109
- * Checks if the pipeline is loaded.
139
+ * Check if the pipeline is fully loaded and ready for processing.
110
140
  *
111
- * @returns True if the pipeline is loaded, false otherwise.
141
+ * @returns True if the pipeline is loaded and ready, false otherwise.
112
142
  */
113
143
  isLoaded() {
114
144
  return this.loaded;
115
145
  }
116
146
  /**
117
- * Loads the pipeline components such as the generator and renderer.
147
+ * Load and initialize the pipeline components.
148
+ * Creates the appropriate renderer and generator based on configuration.
149
+ *
150
+ * @returns Promise that resolves when all components are loaded and ready.
151
+ * @throws Error if an unsupported renderer type is specified in the configuration.
118
152
  */
119
153
  async load() {
120
154
  switch (this.config.render.type) {
121
155
  case "blur":
122
- this.renderer = new k(this.outputCanvas, this.config);
156
+ this.renderer = new f(this.outputCanvas, this.config);
123
157
  break;
124
158
  case "passthrough":
125
- this.renderer = new R(this.outputCanvas, this.config);
159
+ this.renderer = new w(this.outputCanvas, this.config);
126
160
  break;
127
161
  case "replacement":
128
- this.renderer = new v(this.outputCanvas, this.config);
162
+ this.renderer = new k(this.outputCanvas, this.config);
129
163
  break;
130
164
  default:
131
165
  throw new Error("[ladon-ts] Renderer not implemented.");
132
166
  }
133
- await this.renderer.load(), this.generator = new w(this.config), await this.generator.load(), this.loaded = !0;
167
+ await this.renderer.load(), this.generator = new g(this.config), await this.generator.load(), this.loaded = !0;
134
168
  }
169
+ /**
170
+ * Reset the pipeline state by clearing cached mask results.
171
+ * Useful when switching between different processing modes or sources.
172
+ */
135
173
  reset() {
136
174
  this.lastMaskResult = void 0;
137
175
  }
138
176
  /**
139
- * Destroys the pipeline and cleans up resources.
177
+ * Destroy the pipeline and clean up all resources.
178
+ * Properly disposes of the renderer and generator to prevent memory leaks.
179
+ *
180
+ * @returns Promise that resolves when cleanup is complete.
140
181
  */
141
182
  async destroy() {
142
183
  var t, e;
143
- this.reset(), (t = this.renderer) == null || t.destroy(), await ((e = this.generator) == null ? void 0 : e.destroy()), this.frameDataBuffer = void 0, this.loaded = !1;
184
+ this.reset(), (t = this.renderer) == null || t.destroy(), await ((e = this.generator) == null ? void 0 : e.destroy()), this.loaded = !1;
144
185
  }
145
186
  }
146
187
  export {
147
- A as Pipeline
188
+ M as Pipeline
148
189
  };
149
190
  //# sourceMappingURL=pipeline.js.map