Fix Micro-Cycle Death Loops in frame calculation

This commit patches the `SessionImageSender`, `AutoLoopCalculatorWan`,
and `AutoLoopCalculatorLTX` nodes to prevent infinite loops caused by
extreme truncation at the end of video sequences.

- `image.py`: Ensures `SessionImageSender` accepts the entire batch if no
  faces are detected, rather than defaulting to frame 0, which previously
  trapped the workflow in a 1-frame micro-cycle loop.
- `video.py`: Updates `AutoLoopCalculatorWan` to always round the final
  chunk size up to the nearest multiple of 4, removing the strict
  cropping logic that broke the 3D VAE rule.
- `loop.py`: Updates `AutoLoopCalculatorLTX` to always round the final
  chunk size up to the nearest `8n + 1` value, removing the strict
  cropping logic that broke the DiT rule.
This commit is contained in:
Meisoftcoltd
2026-04-08 21:22:08 +00:00
parent df18b573d0
commit 63e84c2aa1
7 changed files with 16 additions and 9 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -129,8 +129,8 @@ class SessionImageSender:
break
if not found:
print(f" -> ⚠️ ALERTA: No se detectó rostro frontal en NINGÚN frame. Salvando el ciclo usando el frame 0 por defecto.")
best_idx = 0
print(f" -> ⚠️ ALERTA: No se detectó rostro frontal en NINGÚN frame. Aceptando todo el lote para evitar bucles infinitos.")
best_idx = batch_size - 1
except Exception as e:
print(f" -> ⚠️ Error en OpenCV al validar: {e}")
else:
+6 -4
View File
@@ -162,14 +162,16 @@ class AutoLoopCalculatorLTX:
print(f" -> ⚖️ Sin caras detectadas. Forzando corte equitativo: {ideal_cut}")
effective_chunk_frames = math.ceil((best_cut - current_pos) / select_every_nth)
# Forzar a 8n + 1
effective_chunk_frames = ((effective_chunk_frames - 1) // 8) * 8 + 1
# Redondear siempre hacia ARRIBA al (8n + 1) más cercano
effective_chunk_frames = ((effective_chunk_frames + 6) // 8) * 8 + 1
if effective_chunk_frames < 9:
effective_chunk_frames = 9 # Mínimo vital LTX
if current_pos + (effective_chunk_frames * select_every_nth) > safe_source_frame_count:
effective_chunk_frames = (safe_source_frame_count - current_pos) // select_every_nth
# ELIMINAMOS el recorte final que rompe la regla 8n + 1
if current_pos + (effective_chunk_frames * select_every_nth) >= safe_source_frame_count:
print(f" -> 🏁 Chunk final LTX detectado. Ajustando a {effective_chunk_frames} frames para mantener regla 8n+1.")
skip_frames = current_pos
+8 -3
View File
@@ -468,13 +468,18 @@ class AutoLoopCalculatorWan:
# 4. Cálculo final del chunk consolidado
effective_chunk_frames = math.ceil((best_cut - current_pos) / select_every_nth)
effective_chunk_frames = (effective_chunk_frames // 4) * 4
# Redondear siempre hacia ARRIBA al múltiplo de 4 más cercano para evitar chunks inválidos
effective_chunk_frames = ((effective_chunk_frames + 3) // 4) * 4
if effective_chunk_frames < 4:
effective_chunk_frames = 4
if current_pos + (effective_chunk_frames * select_every_nth) > safe_source_frame_count:
effective_chunk_frames = (safe_source_frame_count - current_pos) // select_every_nth
# ELIMINAMOS el recorte final que rompe el múltiplo de 4.
# Si pedimos más frames de los que quedan, VHS duplicará el último frame automáticamente,
# salvando así el renderizado sin crashear el 3D VAE.
if current_pos + (effective_chunk_frames * select_every_nth) >= safe_source_frame_count:
print(f" -> 🏁 Chunk final detectado. Ajustando a {effective_chunk_frames} frames para mantener múltiplo de 4.")
skip_frames = current_pos