fix(green_screen): scale chromakey background to frame size, not 1x1

_process_chromakey built the composite background from a 1x1 lavfi color source
and tried to size it with `[0:v]scale=iw:ih`. That scale is a no-op — iw/ih are
the 1x1 source's own dimensions, and there is no cross-reference to the frame.
FFmpeg's overlay then takes the size of its first input (the 1x1 background), so
every processed frame is clipped to a single pixel. The exception fallback never
runs because the primary command exits 0 (a valid 1x1 PNG), and
_reconstruct_video upscales those 1x1 frames — producing a solid-color video
with the keyed subject entirely gone. Total data loss for method="chromakey"
(and method="auto" when it selects chromakey).

Use scale2ref to resize the background to the actual frame dimensions before
overlaying, so the keyed subject is composited at full resolution.

Verified with ffmpeg: a 320x240 green frame with a red subject now produces a
320x240 output with the subject preserved and green replaced by the background,
instead of a 1x1 (then upscaled solid-color) frame.
This commit is contained in:
0xDevNinja
2026-07-09 18:15:05 +05:30
parent de348f15e3
commit df8cf21310
2 changed files with 119 additions and 2 deletions

View File

@@ -465,9 +465,16 @@ class GreenScreenProcessor(BaseTool):
"-i", str(frame),
"-filter_complex",
(
f"[0:v]scale=iw:ih[bg];"
# The background is a 1x1 color source; it MUST be scaled up
# to the frame's dimensions. `scale=iw:ih` on [0:v] alone is a
# no-op (iw/ih are the 1x1 source's own size), and overlay
# takes the size of its FIRST input — so that leaves a 1x1
# canvas and the keyed frame gets clipped to a single pixel,
# producing a solid-color video with the subject gone.
# scale2ref resizes [0:v] to match the frame [1:v] first.
f"[1:v]chromakey=color=0x00FF00:similarity=0.3:blend=0.08[fg];"
f"[bg][fg]overlay=0:0"
f"[0:v][fg]scale2ref[bg][fg2];"
f"[bg][fg2]overlay=0:0"
),
"-frames:v", "1",
str(out_path),