feat(video): route video pipelines through interpolation helper

LTX, video_run, and framepack_worker bypass process_images_inner, so
they call apply_video_interpolation explicitly before save_video. Save
receives already-inflated frames; the sentinel guard skips its own pass.

- LTX and video_run scale mp4_fps by interpolation_factor(p) so duration
  is preserved instead of stretched (LTX is conditioned on source fps)
- FramePack pre-divides at gen time per get_latent_paddings, so save fps
  stays at mp4_fps; worker passes p=None so save call uses
  mp4_interpolate=0 to skip directly
- replaces the inline (mp4_interpolate+1) fps math at LTX with the
  helper-driven equivalent
This commit is contained in:
CalamitousFelicitousness
2026-04-26 03:08:19 +01:00
parent e42f1fd8fb
commit 6acde69467
3 changed files with 34 additions and 5 deletions
+10 -1
View File
@@ -322,6 +322,15 @@ def worker(
if is_last_section:
break
if mp4_interpolate > 0:
from modules.processing_video import apply_video_interpolation
# history_pixels is 5-D (N,C,T,H,W) in [-1,1]; RIFE needs 4-D (T,C,H,W) in [0,1]
x = history_pixels.squeeze(0).permute(1, 0, 2, 3)
x = (x.clamp(-1., 1.) + 1.0) * 0.5
x = apply_video_interpolation(None, x, count=mp4_interpolate)
x = x * 2.0 - 1.0
history_pixels = x.permute(1, 0, 2, 3).unsqueeze(0)
total_generated_frames, _video_filename, _thumb = save_video(
p=None,
pixels=history_pixels,
@@ -334,7 +343,7 @@ def worker(
mp4_sf=mp4_sf,
mp4_video=mp4_video,
mp4_frames=mp4_frames,
mp4_interpolate=mp4_interpolate,
mp4_interpolate=0,
pbar=pbar,
stream=stream,
metadata=metadata,
+12 -3
View File
@@ -563,9 +563,18 @@ def run_ltx(task_id,
except Exception:
aac_sample_rate = 24000
# LTX conditions the model on mp4_fps as the source frame rate; RIFE inflates frames at save time.
# Scale the saved fps by the interpolation factor so the output preserves the user's intended duration.
save_fps = mp4_fps * (mp4_interpolate + 1) if mp4_interpolate > 0 else mp4_fps
if mp4_interpolate > 0:
p.video_interpolate = mp4_interpolate
from modules.processing_video import apply_video_interpolation
# pixels is 5-D (N,C,T,H,W); RIFE needs 4-D (T,C,H,W) in [0,1]
x = pixels.squeeze(0).permute(1, 0, 2, 3)
x = (x.clamp(-1., 1.) + 1.0) * 0.5
x = apply_video_interpolation(p, x, count=mp4_interpolate)
x = x * 2.0 - 1.0
pixels = x.permute(1, 0, 2, 3).unsqueeze(0)
# LTX is conditioned on mp4_fps as the source rate; scale saved fps to keep duration constant
from modules.processing_video import interpolation_factor
save_fps = mp4_fps * interpolation_factor(p)
num_frames, video_file, _thumb = save_video(
p=p,
pixels=pixels,
+12 -1
View File
@@ -160,12 +160,23 @@ def generate(*args, **kwargs):
else:
audio = None
if mp4_interpolate > 0 and pixels is not None:
p.video_interpolate = mp4_interpolate
from modules.processing_video import apply_video_interpolation
# pixels is 5-D (N,C,T,H,W) in [-1,1]; RIFE needs 4-D (T,C,H,W) in [0,1]
x = pixels.squeeze(0).permute(1, 0, 2, 3)
x = (x.clamp(-1., 1.) + 1.0) * 0.5
x = apply_video_interpolation(p, x, count=mp4_interpolate)
x = x * 2.0 - 1.0
pixels = x.permute(1, 0, 2, 3).unsqueeze(0)
from modules.processing_video import interpolation_factor
save_fps = mp4_fps * interpolation_factor(p)
_num_frames, video_file, _thumb = video_save.save_video(
p=p,
pixels=pixels,
audio=audio,
binary=processed.bytes,
mp4_fps=mp4_fps,
mp4_fps=save_fps,
mp4_codec=mp4_codec,
mp4_opt=mp4_opt,
mp4_ext=mp4_ext,