Skip to content

conversion video process Memory Leak: Persistent Memory Bloat When Using VideoSampleSink + OffscreenCanvas in Video Process Callback ? #285

@w550

Description

@w550

let sink = new VideoSampleSink(videoTrack); // otherVideo  PIP 
let ctx
const conversion = await Conversion.init({
  input,
  output,
  video: {
    process: async (sample) => {
       if (!ctx) {
            const canvas = new OffscreenCanvas(sample.displayWidth, sample.displayHeight);
            ctx = canvas.getContext('2d');
       }
         const  samplePIP = await sink.getSample(sample.timestamp);
         samplePIP.close()
         sample.close()
         return ctx.canvas
    }
  }
})

Description
When processing video frames via the Conversion API (with video.process callback) and rendering PIP (Picture-in-Picture) frames using VideoSampleSink + OffscreenCanvas, the application experiences continuous memory growth (memory bloat/leak) over time. Memory usage increases steadily with each processed frame and is never released, even after attempting to clean up resources (e.g., closing samples, nullifying references).
Reproduction Steps
Initialize a VideoSampleSink with a video track for PIP frame extraction
Create an OffscreenCanvas and 2D context (ctx) inside the video.process callback (lazy initialization)
In each frame processing cycle:
Extract a PIP sample via sink.getSample(sample.timestamp)
Render the PIP sample to the OffscreenCanvas
Return the canvas from the process callback
Run the video processing pipeline continuously (e.g., 10+ seconds of video)
Monitor memory usage via browser DevTools (Memory tab) or OS task manager
Expected Behavior
Memory usage should stay stable (or fluctuate within a reasonable range)
Unused Sample objects, canvas resources, and frame data should be garbage-collected (GC) after each processing cycle
No persistent memory growth over time
Actual Behavior
Memory usage increases linearly with each processed frame (e.g., ~50MB growth per minute)
GC does not reclaim memory even after explicit cleanup (e.g., calling sample.close(), nullifying references)
Application eventually becomes unresponsive or crashes due to out-of-memory (OOM) errors

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions