Nodes/H3 Relay/H3RelayRemovalWindow
ComfyUI Node

H3RelayRemovalWindow

The clean boundary frame that stops a removal drifting

By akatz-ai·Created 3 months ago·Updated 10 days ago· 44
H3RelayRemovalWindow
  • source
  • anchor
  • previous
  • source_window
  • anchor
  • history_frames
  • history_audio
◄start0►
◄window_frames22►

Here's the problem a windowed person removal actually has to solve. You are removing someone one second at a time. Window two starts where window one stopped - but window one's last frame is generated, so the person is already gone. If window two is conditioned only on the original footage, it starts from a frame where the person still exists, and the seam is a visible and audible pop.

H3RelayRemovalWindow is the fix. It's internal - generated once per window by H3 Relay Person Remover when it expands into native nodes - and its whole purpose is to hand the sampler the right reference at the right offset.

The four outputs

  • source_window - the slice of green-masked source this window edits, padded to the window length by repeating the last frame if the clip runs out. This is the video reference <Video 1>.
  • anchor - the clean boundary frame. On window one that's clean_first_frame; on every later window it's frame start of what the model already generated, i.e. the person-already-removed picture. This is the image reference, and it's what keeps the reconstruction continuous instead of restarting.
  • history_frames - up to 18 frames of generated video ending at that boundary, so the continuation has real temporal context rather than a naked first frame.
  • history_audio - the same stretch of generated audio, sliced at 24 fps sample offsets, so the audio doesn't reset at every window either.

Note what's not here: the source person's pixels are never handed forward as a guide. The source is the thing being edited; the generated frames are the thing being continued. Mixing those two up is the difference between a clean removal and a window that re-invents a slightly different person each second.

Inputs

Required: source (the masked frames), anchor (the clean first frame) and start (this window's source-frame index). Optional: previous (the running state) and window_frames (default 22; must be a legal H3 size - 22, 39, 56 … 362).

Without previous, there is no generated history yet, so the node returns the anchor frame as both the anchor and the one-frame "history", plus a single silent 48 kHz sample of placeholder audio. That's the honest zero-history case, and it's only correct for window one.

With previous, the node demands a real boundary. It raises Missing generated boundary/history for source window if start is below 17 or beyond the end of what's been generated - the minimum start comes from the 18-frame history needing a boundary at frame 17 or later for continuations.

Why 22 frames, and why that number is load-bearing

H3's temporal grid is 17n+5. The removal default of 22 frames is not arbitrary: the continuation needs 18 frames of history, so a five-frame H3 clip simply cannot supply it. The author's own testing kept 22 as the proven default and treats larger windows as experiments - in a 77-frame test with 39-frame windows the opening window still contained the person even though the assembly and timing were correct. Bigger windows also mean a bigger in-memory latent, so the memory cost rises with the thing you were trying to save time on.

The planner walks windows window_frames - 1 frames apart (21 by default), shifting the final window backwards when needed and trimming the repeated boundary from the delivered output. For a 124-frame source the starts are 0, 21, 42, 63, 84, 102.

Install

Part of the pack:

cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/akatz-ai/h3-relay.git

Manager → H3 Relay works too. You need ComfyUI 0.32.0+ with native H3 and SAM 3 nodes, FFmpeg on PATH, the Ref2VA/Qwen/VAE/SAM3 weights from the pack's manifest, and - still pending public release - the Person Remover LoRA, without which the graph won't run end-to-end.

Snags

  • The removal flickers at a seam. Look at the preview cards either side. Usually the boundary frame is fine but the history is short because you reduced window_frames without changing the history contract - the pack keeps history at 18 for every window size.
  • Source padded, output looks frozen. Tail padding repeats the last real frame to fill the H3 grid; assembly trims it back to your source frame count. If it survives into the output, the parent's source_count is wrong.
  • First window keeps the person. Most often the mask, not the window logic - preview the green-masked source before blaming the render. Past 22 frames it can also be genuine model behaviour.
  • GPU memory spikes with window size. This node's cheaper than the sampler, but it hands over a bigger latent. Stay at 22 unless you have headroom and patience.
CategoryH3 Relay/internal

Inputs (5)

NameTypeDefaultDescription
sourceIMAGE—
anchorIMAGE—
startINT0—
previousoptH3_REMOVAL_STATE—
window_framesoptINT22—

Outputs (4)

NameTypeDescription
source_windowIMAGE—
anchorIMAGE—
history_framesIMAGE—
history_audioAUDIO—