/** * Experimental public entry point for the ActiveFrame Video product block. * @module three-blocks/experimental/active-frame-video */ import type * as THREE from 'three/webgpu'; import type { AFEncodedSource as AFEncodedSourceImplementation } from '../Video/AFEncodedSource.js'; import type { AFFrame as AFFrameImplementation, AFManifest as AFManifestImplementation, AFTrackManifest as AFTrackManifestImplementation } from '../Video/AFContainer.js'; /** Persisted discriminator for the normalized ActiveFrame runtime manifest. */ export declare const ACTIVE_FRAME_TYPE = "active-frame"; /** ActiveFrame runtime manifest version understood by this release. */ export declare const ACTIVE_FRAME_VERSION = 1; /** One encoded frame descriptor and its zero-copy byte view in an ActiveFrame container. */ export type ActiveFrameFrame = AFFrameImplementation; /** Codec, dimensions, timing, and frame index for one ActiveFrame media track. */ export type ActiveFrameTrackManifest = AFTrackManifestImplementation; /** Parsed, validated ActiveFrame v1 container manifest, including an optional alpha track. */ export type ActiveFrameManifest = Readonly; /** * Validate an ActiveFrame container and return its normalized, versioned runtime manifest. * Valid earlier container variants are normalized in memory; malformed bytes and unsupported versions throw. */ export declare function parseActiveFrameManifest(buffer: ArrayBuffer): ActiveFrameManifest; /** Demand-filled encoded source shared by indexed color/depth and optional alpha decoders. */ export type ActiveFrameEncodedSource = AFEncodedSourceImplementation; /** URL, encoded bytes, a fully parsed manifest, or an indexed source accepted by {@link AFDecoder}. */ export type AFDecoderSource = string | ArrayBuffer | { manifest: ActiveFrameManifest; } | ActiveFrameEncodedSource; /** * Sink for requested decoded frames. The callback takes ownership of every delivered frame and * must close it after its final GPU/CPU use. */ export type AFDecoderProcess = (frame: VideoFrame, id: number) => void | Promise; /** Fatal initialization or WebCodecs failure callback. */ export type AFDecoderErrorCallback = (error: unknown) => void; /** Runtime options for {@link AFDecoder}. */ export interface AFDecoderOptions { /** Owned-frame sink; the default closes each delivered frame immediately. */ process?: AFDecoderProcess; /** Notification for initialization or codec failure. */ onError?: AFDecoderErrorCallback; /** WebCodecs hardware-acceleration preference. */ hardwareAcceleration?: HardwareAcceleration; /** Optional WebCodecs colour-space override for decoded samples. */ colorSpace?: VideoColorSpaceInit | null; /** Wall-clock milliseconds allowed for the first requested keyframe output. */ firstDecodeTimeout?: number; } /** Input accepted by {@link AFVideo}. */ export type AFVideoSource = AFDecoderSource; /** Runtime texture and decoder options for {@link AFVideo}. */ export interface AFVideoOptions { /** Three.js colour space assigned to visual texture slots. */ colorSpace?: THREE.ColorSpace; /** Whether decoded frames are flipped vertically for conventional UVs. */ flipY?: boolean; /** Texture magnification filter. */ magFilter?: THREE.MagnificationTextureFilter; /** Texture minification filter. */ minFilter?: THREE.MinificationTextureFilter; /** WebCodecs hardware-acceleration preference. */ hardwareAcceleration?: HardwareAcceleration; /** Optional WebCodecs colour-space override. */ decoderColorSpace?: VideoColorSpaceInit | null; /** Copy luma into data textures instead of sampling colour-managed video textures. */ dataChannel?: boolean; /** Fixed decoded-frame slot budget; two supports ordinary fractional playback. */ slots?: number; /** Copy decoded RGBA frames into stable data-texture slots. */ cpuUpload?: boolean; /** Wall-clock deadline for each decoder's first requested keyframe output. */ firstDecodeTimeout?: number; /** Primary stream selected when the source is indexed. */ encodedStream?: 'color' | 'depth'; } /** Controls whether a bounded frame-set request waits for all requested slots. */ export interface AFVideoSetFramesOptions { /** Await texture readiness; set `false` for fire-and-forget interaction updates. */ wait?: boolean; } /** UV input node accepted by custom ActiveFrame sampling methods. */ export type AFVideoUVNode = THREE.Node<'vec2'>; /** Interpolated RGB output node exposed by an ActiveFrame clip. */ export type AFVideoRGBNode = THREE.Node<'vec3'>; /** Interpolated scalar output node used for alpha and individual data channels. */ export type AFVideoScalarNode = THREE.Node<'float'>; /** Interpolated RGBA output returned by ActiveFrame sampling methods. */ export type AFVideoNode = THREE.Node<'vec4'>; /** A completed frame request, or `null` when a newer request superseded it. */ export type AFVideoFrameResult = AFVideo | null; /** * Frame-accurate runtime decoder for one ActiveFrame clip. * * The decoder owns its WebCodecs `VideoDecoder` and closes frames decoded only while walking a * GOP. The configured process callback owns every requested frame delivered to it. */ export interface AFDecoder { /** Parsed manifest after {@link AFDecoder.loading} resolves; cleared by disposal. */ readonly manifest: ActiveFrameManifest | null; /** * Resolves after manifest parsing and decoder configuration. Rejects on fetch, container, * codec-support, or WebCodecs initialization failure. */ readonly loading: Promise; /** Last frame index handed to the decoder output callback. */ readonly frame: number | null; /** Last requested frame index whose process callback completed. */ readonly frameProcessed: number | null; /** Whether encoded chunks remain queued on the underlying codec. */ readonly busy: boolean; /** Whether requested frames have not yet reached the process callback. */ readonly pending: boolean; /** Request one clamped integer frame. */ setFrame(index: number): void; /** Request a set of frame indices, decoding each required GOP at most once. */ request(frames: Iterable): void; /** * Close the owned decoder and stop delivery. Idempotent; frames already delivered to the * process callback remain callback-owned and must still be closed there. */ dispose(): void; } /** * GPU-resident runtime playback and sampling facade for one ActiveFrame clip. * * The instance owns its decoders, decoded `VideoFrame`s, and fixed texture slots. Request frame * changes before rendering materials that sample its output nodes. */ export interface AFVideo { /** Parsed container manifest after {@link AFVideo.ready} resolves. */ readonly manifest: ActiveFrameManifest | null; /** Number of frames in the primary media track. */ readonly totalFrames: number; /** Fixed number of decoded texture slots allocated by this instance. */ readonly slotCount: number; /** Whether the container includes a separately decoded alpha track. */ readonly hasAlpha: boolean; /** Resolves after the first frame reaches a texture, or with `null` after early suspension/disposal. */ readonly firstFrame: Promise; /** * Resolves after manifest parsing and decoder configuration. Rejects on fetch, container, * codec-support, or WebCodecs initialization failure. */ readonly ready: Promise; /** Interpolated RGBA node sampled at the material's current UV. */ readonly node: AFVideoNode | null; /** Interpolated RGB node. */ readonly rgb: AFVideoRGBNode; /** Interpolated alpha node, or `null` before the sampling graph exists. */ readonly a: AFVideoScalarNode | null; /** Named compatibility output for assigning directly to a material opacity node. */ readonly alphaNode: AFVideoScalarNode | null; /** Sample the current interpolated frame set at a custom UV node. */ sample(uvNode: AFVideoUVNode): AFVideoNode; /** Sample all assigned bounded slots using the weights from the latest `setFrames()` call. */ sampleWeighted(uvNode: AFVideoUVNode): AFVideoNode; /** Sample one physical slot without applying temporal interpolation. */ sampleSlot(slot: number, uvNode: AFVideoUVNode): AFVideoNode; /** Request a fractional frame and resolve after its visible bracket reaches the textures. */ setFrame(frame: number): Promise; /** Request an arbitrary weighted frame set within the fixed slot budget. */ setFrames(indices: readonly number[], weights?: readonly number[], options?: AFVideoSetFramesOptions): Promise; /** Park decoders and release their admission leases while retaining the displayed textures. */ suspend(): void; /** Recreate parked decoders against the retained source without replacing texture identities. */ resume(): Promise; /** * Close owned decoders and frames and dispose owned textures. Idempotent; pending frame * readiness resolves with `null`, and consuming materials remain caller-owned. */ dispose(): void; } interface AFDecoderConstructor { readonly prototype: AFDecoder; new (source: AFDecoderSource, options?: AFDecoderOptions): AFDecoder; } interface AFVideoConstructor { readonly prototype: AFVideo; new (source: AFVideoSource, options?: AFVideoOptions): AFVideo; } /** * Construct an ActiveFrame decoder without wrapping its implementation object. Initialization * errors reject `loading`; malformed immediate arguments may throw during construction. */ export declare const AFDecoder: AFDecoderConstructor; /** * Construct ActiveFrame GPU playback without wrapping its implementation object. Initialization * errors reject `ready`; texture slots allocated at construction are released by `dispose()`. */ export declare const AFVideo: AFVideoConstructor; export {};