Skip to content

MSTP's VideoFrame lifetime management model assumes a single consumer #56

@jan-ivar

Description

@jan-ivar

MediaStreamTrackProcessor appears to expect consumers to call VideoFrame.close() manually. Unfortunately, this:

  1. Assumes a single consumer per VideoFrame
  2. Creates a footgun where consumers may forget to call this method, with potentially devastating OS-level side-effects

Ditto MediaStreamTrackGenerator which calls VideoFrame.close() implicitly, preventing reuse with another sink. It too:

  1. Assumes a single consumer per VideoFrame

VideoFrames are immutable objects (with a necessary mutable close() method because we don't want to wait for GC, a pattern that works well for a single owner).

A benefit of immutability is supposed to be shareability, so we should be able to tee a stream:

const [readable1, readable2] = new MediaStreamTrackProcessor({track}).readable.tee();

await Promise.all([
  readable1.pipeThrough(new MyTransform(640)).pipeTo(sink1),
  readable2.pipeThrough(new MyTransform(320)).pipeTo(sink2)
]);

...and this would work, except it breaks if MyTransform calls VideoFrame.close().

IOW, since sources may have multiple sinks, it seems better for sources to own the VideoFrames it doles out, and manage their lifetime.

source -.---> sink1
        `---> sink2

Proposal

  • Have MediaStreamTrackGenerator manage lifetime of VideoFrames it passes to immediate sinks.
    • (and any transform stream that wants to pass through a VideoFrame needs to copy or renew it somehow)
  • Stop having MediaStreamTrackGenerator call VideoFrame.close() and rely on the producer to do this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions