# Source: FrameProvider.js

    /**
     * This is a class for image planes
     * @typedef FrameProvider_IPlane
     * @type {object}
     * @member {function} dereference - removes internal reference to an object so it can be garbage collected
     * @member {function} GetSize - gets size of the plane in bytes
     * @member {function} GetWidth
     * @member {function} GetHeight
     * @member {function} GetBytesPerPixel
     * @property {function} GetByte - gets byte on the specified index (idx) => byte
     * @property {function} SetByte - sets byte on the specified index (idx, byte) => void
     * @property {function} JSBuffer - gets bytearray
     * @property {function} SetBuffer - sets bytearray
     */

    /**
     * This is a class for images
     * @typedef FrameProvider_Image
     * @type {object}
     * @property {function} GetSize - gets total size of the image in bytes
     * @property {function} GetWidth
     * @property {function} GetHeight
     * @property {function} GetPlaneCount - gets number of planes
     * @property {function} GetPlane - gets a plane on the specified index
     */

    /**
     * This callback type is called `FrameProviderCallback`
     * @callback FrameProviderCallback
     * @param {number} id
     * @param {ImageData} imageData
     */

    /**
     * An interface used to provide input image data for processing.
     * API users should obtain a reference to this interface by using SDKProvider::GetFrameProvider function.
     */
    export class FrameProvider {
    	constructor(modulesManager) {
    		this.module = modulesManager.modules.visage.module;
    		this.bscFrameProvider = this.module.GetFrameProvider();
    	}

    	/**
    	 * @function SetCallback
    	 * @param {FrameProviderCallback} callback
    	 * @param {boolean} withImageData flag to return frame as JS ImageData as the third arg. Defaults to `true`
    	 * @returns {number} handle of callback you can use to clear it
    	 */
    	SetCallback(callback) {
    		return this.bscFrameProvider.SetCallback(callback);
    	}

    	ClearCallback(handle) {
    		this.bscFrameProvider.ClearCallback(handle);
    	}

    	frame = undefined;
    	/**
    	 * Enqueues a new ImageData object for processing, replacing the last queued ImageData object.
    	 * ImageData object is described on the following <a href="https://developer.mozilla.org/en-US/docs/Web/API/ImageData">link</a>.
    	 *  <br/>
    	 *  <br/>
    	 * Internally the engine uses dedicated requestAnimationFrame loop. When requestAnimationFrame is triggered the engine obtaines the last queued frame from IFrameProvider using GetFrame method.
    	 * It is possible that no frame are processed or that the same frame is processed multiple times.
    	 * @param {ImageData} imgData - input image data
    	 */
    	AddFrame(imgData) {
    		const startTime = window.makeupsdkLogger?.GetTimestamp();
    		const frameId = this.bscFrameProvider.AddFrame(imgData);
    		window.makeupsdkLogger?.Log({ message:"add_frame", id: frameId, isStarting: true, time: startTime});
    		window.makeupsdkLogger?.Log({ message:"track", id: frameId, isStarting: true, time: startTime});

    		return frameId;
    	}
    }