-
-
Notifications
You must be signed in to change notification settings - Fork 201
Description
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