mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
feat(video): support first-last-frame for Wan 2.2 I2V
The I2V path forwards a last-frame image to the pipeline when one is supplied and the loaded pipeline accepts it, turning the run into first-last-frame interpolation. supports_last_frame() gates on the pipeline taking a last_image argument and not running expand_timesteps, which conditions on the first frame only, so a model that cannot use a last frame logs a warning instead of silently ignoring it.
This commit is contained in:
@@ -67,7 +67,13 @@ def generate(*args, **kwargs):
|
||||
if init_image is None:
|
||||
return video_utils.queue_err('No input image provided. Please upload or select an image.')
|
||||
p.task_args['image'] = images.resize_image(resize_mode=2, im=init_image, width=p.width, height=p.height, upscaler_name=None, output_type='pil')
|
||||
log.debug(f'Video: op=I2V init={init_image} resized={p.task_args["image"]}')
|
||||
if last_image is not None and video_utils.supports_last_frame(shared.sd_model):
|
||||
p.task_args['last_image'] = images.resize_image(resize_mode=2, im=last_image, width=p.width, height=p.height, upscaler_name=None, output_type='pil')
|
||||
log.debug(f'Video: op=FLF2V init={init_image} last={last_image} resized={p.task_args["image"]}')
|
||||
elif last_image is not None:
|
||||
log.warning(f'Video: op=I2V model="{model}" last frame not supported, ignoring')
|
||||
else:
|
||||
log.debug(f'Video: op=I2V init={init_image} resized={p.task_args["image"]}')
|
||||
elif 'FLF2V' in model:
|
||||
if init_image is None:
|
||||
return video_utils.queue_err('No input image provided. Please upload or select an image.')
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import inspect
|
||||
from PIL import Image
|
||||
from installer import install
|
||||
from modules import shared, sd_models, timer, errors, devices
|
||||
@@ -19,6 +20,18 @@ def get_url(url):
|
||||
return f'<a href="{url}" target="_blank" rel="noopener noreferrer" class="video-model-link">{url}</a><br><br>' if url else '<br><br>'
|
||||
|
||||
|
||||
def supports_last_frame(model):
|
||||
# last-frame (FLF2V) conditioning needs a pipeline whose __call__ accepts `last_image`.
|
||||
# wan 2.2 5b accepts the arg but masks timesteps from the first frame only, so it drops the last frame.
|
||||
try:
|
||||
params = list(inspect.signature(type(model).__call__, follow_wrapped=True).parameters)
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
if 'last_image' not in params:
|
||||
return False
|
||||
return not getattr(getattr(model, 'config', None), 'expand_timesteps', False)
|
||||
|
||||
|
||||
def check_av():
|
||||
install('av')
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user