ComfyUI Node

CPA TrackMasks

Getting SAM3's video masks out without the 12 GB tax

By rik-python·Created about a month ago·Updated 9 days ago· 50
CPA TrackMasks
  • masks
  • masks_back
  • mask
◄start0►
◄count1►
◄width1920►
◄height1080►

CPA TrackMasks is the smallest node in this pack and one of the more opinionated. Its job: take what SAM3's video tracker produces and hand back a plain MASK stack - one mask per frame, nothing else.

Why does that need to exist? Because the obvious route from SAM3 propagation to a usable mask is the SAM3VideoOutput node in ComfyUI-SAM3, and that node renders the full-length RGB plus a visualisation batch as well. The pack's author measured it at roughly 90 seconds and about 12 GB per track for output that a matting pipeline throws away. TrackMasks builds only the mask, and only for the frames actually being rendered.

SAM3 is the reason any of this works - as our SAM panel puts it, it's the current masking tier, and text-prompted subject selection is exactly what it's for. Tracking a chosen subject across a shot is the piece that makes "matte this person" a one-click operation instead of a roto job.

Inputs

masks is the odd one: it takes SAM3_VIDEO_MASKS, the propagation output from ComfyUI-SAM3 - a per-frame dict of object masks. You can't feed it an IMAGE or a MASK; the type is its own thing.

start and count pick the window out of that dict to materialise. This is the whole optimisation: SAM3 tracks the entire plate, but the pack only needs masks for the frames it's rendering, which begin at the frame you clicked on. Everything before it is skipped rather than built and discarded.

width and height are the output resolution, and they need to match what the rest of the pipeline expects. SAM3 has been fed a proxy MP4 rather than the original frames, and MP4 requires even dimensions - so the tracker sees an edge-replicated, possibly one- or two-pixel-larger frame. TrackMasks crops that back (m[:height, :width]) and, if the sizes still disagree, bilinear-resizes. Getting this wrong doesn't crash anything; it produces masks that are subtly offset from the plate, which then shows up as an alpha edge that's a pixel off. That's a miserable bug to chase by eye, so the resize is handled here rather than left to the user.

Output

mask, a MASK batch of count frames at height × width, float16.

Two behaviours worth knowing. If a frame is missing from the propagation dict, you get a zero mask for it rather than an error. If SAM3 returns an empty tensor for a frame - the object lost, or out of shot - that frame is also zero, deliberately. count frames out, always, aligned to start. Downstream stages can then index masks positionally without checking lengths, which is the kind of boring reliability that stops a 247-frame render from dying at frame 180.

Values are normalised to 0–1 on the way: if SAM3 hands back 0–255 byte masks, they're divided by 255; multiple objects at a frame are max-combined (so the picker's shift-clicks stack into one mask); and everything is clamped and cast to half precision to keep a long shot's mask stack in RAM.

Install

Part of the pack - nothing extra, but it does need the SAM3 side present or nothing upstream will produce its input type:

cd ComfyUI/custom_nodes
git clone https://github.com/rik-python/ComfyUI-Comfy-Pro-Alpha-Generator.git
pip install -r ComfyUI-Comfy-Pro-Alpha-Generator/requirements.txt

Then install ComfyUI-SAM3 through ComfyUI Manager; the pack ships a preflight check that names the missing pack instead of failing halfway through a run. The sam3.safetensors weights (~3.5 GB) download themselves into models/sam3/ on first use. ComfyUI 0.38+ required - SAM3 tracking in this pipeline relies on the newer video-mask plumbing. Non-commercial licence, as with the whole pack.

Should you touch it

Probably not, and I'd rather say so than invent a use case. It's hidden from the node menu (the pack marks every internal stage deprecated so it stays executable but out of search), and the generator wires it for you with the right start, count and dimensions already filled in from your pick frame and plate size.

The one situation where knowing about it helps: if you're hand-building a SAM3 tracking graph of your own and you've watched ComfyUI balloon by 12 GB per track, this is the swap you want - mask only, windowed, no RGB render. That's a real technique even outside this pack.

And if your matte drifts a pixel sideways relative to the plate, or drops out for a stretch in dark or blurred frames, the things to check are here and one stage up: the sam3_threshold on the generator (lower it to 0.2 if the subject drops out; raise to 0.4–0.5 if the track jumps onto something else), and whether the plate dimensions you handed the pipeline match the ones you're rendering at. A zero mask for a handful of frames is SAM3 saying it lost the object, not a crash.

CategoryComfy Compositing/internal

Inputs (6)

NameTypeDefaultDescription
masksSAM3_VIDEO_MASKS—
startINT0—
countINT1—
widthINT1920—
heightINT1080—
masks_backoptSAM3_VIDEO_MASKS—

Outputs (1)

NameTypeDescription
maskMASK—