
    
3j͘                         S SK r S SKJr  S SKrS SKrSSKJrJrJr  SSK	J
r
Jr  SSKJr  \ " S S5      5       r\ " S	 S
5      5       r\ " S S5      5       r\" SS9 " S S5      5       r\" SS9 " S S5      5       rg)    N)	dataclass   )LTXVBaseSamplerLTXVExtendSamplerLTXVInContextSampler)LTXVDilateLatentLTXVSelectLatents)
comfy_nodec                       \ rS rSr% Sr\\S'   \\S'   \\S'   \R                  \S'   \	\S'   \\S'   \
\S	'   \
\S
'   \
\S'   \
\S'   \
\S'   \
\S'   \
\S'   Srg)
TileConfig   z*Configuration for spatial tile processing.tile_latentstile_guiding_latentstile_negative_index_latentstile_keyframeskeyframe_per_tile_indicestile_normalizing_latentstile_height
tile_widthvhvertical_tileshorizontal_tiles
first_seed N)__name__
__module____qualname____firstlineno____doc__dict__annotations__torchTensorlistint__static_attributes__r       M/home/wildlama/comfy/ComfyUI/custom_nodes/ComfyUI-LTXVideo/looping_sampler.pyr   r      sS    4!%%LL ##""O
F
FOr(   r   c                       \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\S'   \\S'   \\S	'   \\S
'   \\S'   \\S'   \\S'   \\S'   \\S'   \\S'   \\S'   Sr	g)SamplingConfig   z&Configuration for sampling parameters.temporal_tile_sizetemporal_overlaptemporal_overlap_cond_strengthcond_image_strengthguiding_strengthadain_factoroptional_negative_index optional_negative_index_strengthoptional_positive_conditioningstime_scale_factorwidth_scale_factorheight_scale_factorper_tile_seed_offsetsguiding_start_stepguiding_end_stepr   N)
r   r   r   r   r    r&   r"   floatr%   r'   r   r(   r)   r+   r+      s_    0$))  &++%))r(   r+   c                   V    \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\S'   \\S'   S	rg
)ModelConfig4   z#Configuration for model components.modelvaenoisesamplersigmasguiderr   N)r   r   r   r   r    objectr"   r'   r   r(   r)   r>   r>   4   s#    -M	KMONNr(   r>   LTXVLoopingSampler)namec                       \ rS rSr\S 5       rSrSrSrSr	S r
S rS	\S
\S\4S jrS rS rS r SS jrS rS r           SS jrSrg)rG   @   c                 P   SSS04SSS04SSS04SSS	04S
SS04SSS04SSS04SSSSSSS.4SSSSSSS.4SSSSSSS.4SSSSSSS.4SSSSSS S.4SS!S!S"S#S$.4SS!S!S"S%S$.4SS!S!SS&S$.4S'.S(SS)04SSS*04SSSSSS+S.4S,SS-04SSS.04SS/S/SS0S$.4SSS/SS1S$.4S2S3S4S5.4SSS604S7.	S8.$ )9NMODELtooltipzThe diffusion model to use.VAEzThe VAE to use.NOISEzThe noise to use.SAMPLERzThe sampler to use.SIGMASzThe sigmas to use.GUIDERz/The guider to use, must be a STGGuiderAdvanced.LATENTzvThe latents to use for creating the long video, they can be guiding latents or empty latents when no guidance is used.INTP           znThe size of the temporal tile to use for the sampling, in pixel frames, in addition to the overlapping region.)defaultminmaxsteprM      z8The overlap between the temporal tiles, in pixel frames.FLOAT      ?g        g{Gz?z`The strength of the conditioning on guiding latents, when optional_guiding_latents are provided.g      ?zPThe strength of the conditioning on the latents from the previous temporal tile.z=The strength of the conditioning on the optional_cond_images.r      z#Number of horizontal spatial tiles.)rY   rZ   r[   rM   z!Number of vertical spatial tiles.zOverlap between spatial tiles.)r@   rA   rB   rC   rD   rE   latentsr-   r.   r1   r/   r0   r   r   spatial_overlapIMAGEzThe image to use for conditioning the first frame in the video (i2v setup). If not provided, the first frame will be unconditioned (t2v setup). The image will be resized to the size of the first frame.zGThe latents to use for guiding the sampling, typically with an IC-LoRA.zThe strength of the AdaIn operation used to fix the statistics of each new generated temporal tile, to prevent accumulated oversaturation.CONDITIONINGzmOptional way to provide changing positive prompts, one per temporal tile, using the MultiPromptProvider node.zSpecial optional latents to condition on a negative index before each new temporal tile as a way to provide long term context during video generation.r   z7The step at which the guiding latents start to be used.z6The step at which the guiding latents stop to be used.STRING0z}The indices of the keyframes to use for the sampling, separated by commas. The indices are counted from the end of the video.)rY   rM   zThe latents to use for normalizing the output latents, they will be used to normalize the output latents to the same statistics as the input latents.)	optional_cond_imagesoptional_guiding_latentsr2   r5   optional_negative_index_latentsr:   r;   optional_cond_image_indicesoptional_normalizing_latents)requiredoptionalr   ss    r)   INPUT_TYPESLTXVLoopingSampler.INPUT_TYPESE   s`    "I/L#MN	+<=>!I/B#CD%	3H'IJ#i1E%FG QR
 !  $\ #%!# ! $T	' #%!! !#]	% #&"" $ $F	% #&"" $#u	3 #&"" $#b	( #$  #H	% #$  #F	# #$  #C	$i]@ !  $o) !#l- #&"" $ $p	! #!  $S4 !  $|4 #$ ##\	' #' ##[	% #& $c0 !  ${1yBb
 b	
r(   )rS   )denoised_outputsamplesamplingc                     Uc  gUS   SS2SS2SS2X#2XE24   nSU;   a  US   b  US   SS2SS2SS2X#2XE24   nXgS.$ SU0$ )z.Extract spatial tile from a latent dictionary.Nsamples
noise_mask)rv   rw   r   )selflatent_dictv_startv_endh_starth_endtile_samples
tile_maskss           r)   _extract_latent_spatial_tile/LTXVLoopingSampler._extract_latent_spatial_tile   sr    "9-aAw}gm.ST;&;|+D+P$\21a5J  ,FF|,,r(   c                     U R                  XXxU	5      nU R                  X&XxU	5      nU R                  X6XxU	5      nU R                  XFXxU	5      nUb"  Xj-  nXz-  nX-  nX-  nUSS2UU2UU2SS24   nOSnUUUUU4$ )zAExtract spatial tiles from all inputs for a given spatial region.N)r   )rx   ra   rh   ri   rk   optional_keyframesrz   r{   r|   r}   r8   r7   r   r   r   r   img_h_start	img_h_endimg_w_start	img_w_endr   s                        r)   _extract_spatial_tile(LTXVLoopingSampler._extract_spatial_tile   s      88ee

  $@@$uu 

 '+&G&G+ee'
#
 $(#D#D(55$
  )!7K3I!6K2I/;y(+i*?BN "N  '$
 	
r(   tile_configsampling_configmodel_configc                    SnSnSn[        [        [        SUR                  S   R                  S   UR
                  -   UR                  -
  UR
                  UR                  -
  5      [        UR
                  UR                  S   R                  S   UR
                  -   UR                  -
  UR
                  UR                  -
  5      5      5       GH  u  nu  pUR                  bS  [        5       R                  UR                  U[        U	S-
  UR                  S   R                  S   S-
  5      5      S   n
OSn
[        5       R                  UR                  U[        U	S-
  UR                  S   R                  S   S-
  5      5      S   n[        SUS[        U	S-
  UR                  S   R                  S   S-
  5      5        U R                  UR                  U5      nUR                  bk  [        5       R                  UR                  U[        U	S-
  UR                  S   R                  S   S-
  5      5      S   nSn[        S	UR                  5        OUnS
n[        SUR                  5        U R!                  UR"                  UUR$                  UR&                  UR(                  UR*                  U5      UR,                  l        U R1                  UR2                  UR4                  U5      nUR6                   VVs/ s H  u  nnUU:X  d  M  UPM     nnnU(       a  UR8                  bz  [:        R<                  " [        UR6                  5       VVVs/ s H/  u  nu  nnUU:X  d  M  UR8                  U   R?                  S5      PM1     snnn5      n[        SU SU 35        OSn[        SU S35        SRA                  U Vs/ s H  n[C        U5      PM     sn5      nUS:X  Ga  UR                  b  [E        5       RG                  URH                  UURJ                  URL                  UR,                  U
UUSURN                  URP                  URR                  UURT                  URV                  URX                  URZ                  S9S   nGO
[]        5       RG                  UR^                  URH                  UR,                  URJ                  URL                  U[        UR
                  UR                  S   R                  S   5      S-
  UR`                  -  S-   URb                  URd                  -  URf                  URh                  -  UUSSURT                  URN                  URP                  URR                  UURX                  URZ                  S9S   n[j        Rl                  " U5      nO[o        5       RG                  UR^                  URH                  URJ                  URL                  UR,                  UUS   R                  S   UR                  -
  UR`                  -  UR                  UR`                  -  UURp                  URV                  URT                  U
UUUUUR                  URN                  URP                  URR                  UURX                  URZ                  S9S   nUS-  nGM     U$ s  snnf s  snnnf s  snf )z6Process all temporal chunks for a single spatial tile.r   Nrv      r   z"Processing temporal chunk at indextoTzKNormalizing latents provided, normalizing per frame and channel with factorFzVNo normalizing latents provided, normalizing per channel using first chunk with factorzChunk z keyframe indices: z has no keyframes,)rA   rE   rC   rD   rB   guiding_latentsrg   optional_cond_indices
num_framesri   r3   r4   optional_initialization_latentsr0   r1   r:   r;   center   )r@   rA   rB   rC   rD   rE   r   widthheightrg   r   cropcrfstrengthri   r3   r4   r   r:   r;   )r@   rA   rC   rD   rB   ra   num_new_framesframe_overlaprE   r   r1   r0   rh   rg   r   optional_reference_latentsnormalize_per_framer2   ri   r3   r4   r   r:   r;   )9	enumeratezipranger   shaper-   r.   r   r	   select_latentsrZ   print_get_per_tile_valuer9   r   r2   _calculate_tile_seedr   r   r   r   r   rB   seed_prepare_guider_for_chunkrE   r5   r   r   r#   cat	unsqueezejoinstrr   rs   rA   rC   rD   r   r3   r4   r0   r1   r:   r;   r   r@   r6   r   r7   r   r8   copydeepcopyr   r/   )rx   r   r   r   chunk_indextile_out_latentsfirst_tile_out_latentsi_temporal_tilestart_index	end_indexguiding_latent_chunklatent_chunkseed_offsetnormalizing_latent_chunkr   
new_guider
tile_indexin_tile_indexthis_chunk_keyframe_indices
i_keyframethis_chunk_keyframesis                         r)   _process_temporal_chunks+LTXVLoopingSampler._process_temporal_chunks6  s8    !%9B,,Y7==a@%889%667 $66%667 #66,,Y7==a@%889%667 $66%667:
5O5k( //;'8':'I'I44!A#88CII!LqP( ($ (,$,.==((IM;#;#;I#F#L#LQ#ORS#ST 	L 4IM;#;#;I#F#L#LQ#ORS#ST	 2255K 33?+<+>+M+M88!A#<<YGMMaPSTT, ,( '+#a#00
 ,B(&+#l#00
 '+&?&?&&**,,'L# 77##??J 4?3X3X+3X/Z0 3X ( +
 +{/I/I/U',yy JS'AAJJEZ)D*m &8	 L22:>HHKJ($ _--@A\@]^ (,$//@AB*-((!<=!<AQ!<=+' a33?';'='D'D(,,) , 4 4+22*00(<-A.I#%8C8_8_0?0W0W9H9i9i8D,;,O,O)8)I)I+:+M+M)8)I)I# (E ($ %($( (7'8'?'?*00(,,*00 , 4 4+22) / B B + 8 8 C I I! L  	  *;;$< $ *44)<<=*66)== >-A.I%!0!D!D8C8_8_0?0W0W9H9i9i8D+:+M+M)8)I)I= (@ (> ?($@ *.7G)H&#4#6#=#=&,,$(((00'..&,,,$Y/55a8)::; &77	$8
 #2"B"B%77#8%,KK%4%E%E(7(K(K-A)=*E/G(;!0!=!=4?4[4[,;,S,S5D5e5e4@'6'I'I%4%E%E; $> $< =$ @ 1KQ:
T  e+ >s   [ [ [."[[
c	           
         [         R                  " XUS9n	US:  aF  [         R                  " SSXgUS9n
U	SS2SS2SS2SS2SU24==   U
R                  SSSSS5      -  ss'   X4S-
  :  aG  [         R                  " SSXgUS9n
U	SS2SS2SS2SS2U* S24==   U
R                  SSSSS5      -  ss'   US:  aF  [         R                  " SSXgUS9nU	SS2SS2SS2SU2SS24==   UR                  SSSSS5      -  ss'   X%S-
  :  aG  [         R                  " SSXgUS9nU	SS2SS2SS2U* S2SS24==   UR                  SSSSS5      -  ss'   U	$ )z*Create blending weights for spatial tiles.devicedtyper   r   Nr   )r#   oneslinspaceview)rx   
tile_shaper   r   r   r   rb   r   r   tile_weightsh_blendv_blends               r)   _create_spatial_weights*LTXVLoopingSampler._create_spatial_weights  sf    zz*5I q5nnQ?QVWGAq!%5o%556',,q!QPQSU:VV6!##nnQ?QVWGAq!o%5%6677<<1aQRTV;WW7 q5nnQ?QVWGAq"2?"2A56',,q!QPRTU:VV6!!nnQ?QVWGAq?"2"3Q677<<1aQSUV;WW7r(   c                 ,    UX#U-  -  -   XT-  -   U-   U-   $ )zBCalculate the seed value for a specific temporal and spatial tile.r   )rx   r   r   r   r   r   r   r   s           r)   r   'LTXVLoopingSampler._calculate_tile_seed-  s=     .>>?@"#  		
r(   c                 8    U[        U[        U5      S-
  5         $ )z\Get a value from a per-tile configuration list, using the last value if the list is shorter.r   )rZ   len)rx   
value_listr   s      r)   r   &LTXVLoopingSampler._get_per_tile_value@  s    #j#j/A*=>??r(   Nc                    ^ US:X  a  UnUR                  S5       Vs/ s H  oS" UR                  5       5      PM     nnU4S jnTb  U Vs/ s H
  o" U5      PM     nnU$ s  snf s  snf )zNParse a comma-separated configuration string into a list with type conversion. r   c                    > U S:  a  U T-   $ U $ )Nr   r   )valueoptional_total_sizes    r)   handle_negative_indexOLTXVLoopingSampler._parse_comma_separated_string.<locals>.handle_negative_indexL  s    qy222Lr(   )splitstrip)	rx   config_stringdefault_valueconverter_funcr   itemvaluesr   r   s	       `    r)   _parse_comma_separated_string0LTXVLoopingSampler._parse_comma_separated_stringD  sv     B)M;H;N;Ns;ST;S4..;ST	
 *@FGu+E2FG U Hs   A A%c                     Ub]  [         R                   " U5      nUR                  u  pV[        U[        U5      S-
  5      nUR	                  X'   U5        X'   U4Ul        U$ U$ )zRPrepare the guider for a specific chunk, handling optional positive conditionings.r   )r   	raw_condsrZ   r   	set_conds)rx   rE   r5   r   r   positivenegativeconditioning_indexs           r)   r   ,LTXVLoopingSampler._prepare_guider_for_chunkU  s|     +66*J!'!1!1H!$S!@AAE"   /C
 0C$J  Mr(   c           	      l   / nU H  nXd:  a  [        SU SU S35        M  XbS-
  :  a  UR                  SU45        M9  X#-
  nSn X-  S-
  n	X(U-  -   S-
  S-
  n
[        SU SU	 S	U
 35        Xj::  a9  Xi-
  S-
  nX:  a  US-  nUS:X  a  UnOX-
  nXl-
  S-
  nUR                  X45        M  US-  nMm     U$ )
a  
Calculate which temporal tile each keyframe falls into.

Returns a list of tuples (temporal_tile_index, in_tile_index) for each keyframe.
- temporal_tile_index: which temporal tile the keyframe falls in
- in_tile_index: index within that specific temporal tile

First tile: frames [0, temporal_tile_size - 8] (size = temporal_tile_size - 8 + 1)
Subsequent tiles follow the pattern from _process_temporal_chunks:
- Tile n starts at: n * (temporal_tile_size - temporal_overlap)
- Tile n ends at: temporal_tile_size + n * (temporal_tile_size - temporal_overlap) - 1

For subsequent tiles, keyframes with in_tile_index < temporal_overlap
don't count as falling in that tile.
zKeyframe index z is greater than num_frames z
, skipping   r   r   zTile z starts at z and ends at )r   append)rx   keyframe_indicesr-   r.   r   resultkeyframe_index	tile_stepr   
tile_starttile_endr   
prev_starts                r)   $_calculate_keyframe_per_tile_indices7LTXVLoopingSampler._calculate_keyframe_per_tile_indicesl  s)   $ .N+%n%55QR\Q]]gh Q 66q.12 +=IJ'3a7
-Y0FFJQNJ<{:,mH:V
 "-&3a7 " %7"a
%?,:M *4)?J . ;a ? * MM:"=>a
= % /d r(   c                    US   n[        U[        R                  R                  5      (       a$  [	        UR
                  5      S:X  a  [        S5      eUR                  u  nnnnn UR                  u  n!n"n#U
U!-  n
UU!-  nUR                  n$U R                  US[        5      nU R                  US[        UU!-  S-
  S9n%U R                  U%U
U!-  UU!-  UU!-  S-
  5      n&[        SU& 35        UbX  [        R                  R                  UR!                  SS	5      U U"-  UU#-  S
SS9R!                  S	S5      R#                  SS	5      n'OS n'Ub  US   n(UR                  S   U(R                  S   :X  d   S5       eUR                  S   U(R                  S   -  S:X  a#  UR                  S   U(R                  S   -  S:X  d   S5       eUR                  S   U(R                  S   -  n)UR                  S   U(R                  S   -  n*[%        5       R'                  UU*U)5      S   nUUS	-
  U-  -   U-  n+U US	-
  U-  -   U-  n,S n-S n.[)        U5       GH  n/[)        U5       GH  n0U0U,U-
  -  n1U/U+U-
  -  n2U0US	-
  :  a  [+        U1U,-   U 5      OU n3U/US	-
  :  a  [+        U2U+-   U5      OUn4U4U2-
  n5U3U1-
  n6[        SU/ SU0 S35        [        SU2 SU4 SU1 SU3 S3	5        [        SU5 SU6 35        U R-                  UUUUU'U2U4U1U3U#U"5      u  n7n8n9n:n;[/        U7U8U9U:U&U;U5U6U/U0UUU$S9n<[1        U
UUUUU	U9b  SU9S   R                  S   -  OSUUU!U"U#UUUS9n=[3        UUUUUUS9n>U R5                  U<U=U>5      n?U-cV  U?S   R                  S   n@[6        R8                  " UUU@UU UR:                  UR<                  S9n-[6        R>                  " U-5      n.U?S   RA                  U-R:                  5      nAU RC                  UAR                  U/U0UUUU-R:                  U-R<                  5      nBU-S S 2S S 2S S 2U2U42U1U324==   UAUB-  -  ss'   U.S S 2S S 2S S 2U2U42U1U324==   UB-  ss'   GM     GM     U-U.S-   -  n-SU-0nCU$Ul	        UC4$ )Nrv   r   z^LoopingSampler currently does not support Audio Visual latents. please only use video latents.rf   r   )r   zKeyframe per tile indices: r   r   bilinearr   )r   r   zQThe number of frames in the latents and optional_guiding_latents must be the same      z`The ratio of the height and width of the latents and optional_guiding_latents must be an integerzProcessing spatial tile at row z, col :z  Position: (z, )z  Size: x)r   r   r   r   r   r   r   r   r   r   r   r   r   )r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   )r@   rA   rB   rC   rD   rE   r   g:0yE>)"
isinstancecomfynested_tensorNestedTensorr   tensors
ValueErrorr   downscale_index_formular   r   r&   r   r   utilscommon_upscalemovedimclampr   dilate_latentr   rZ   r   r   r+   r>   r   r#   zerosr   r   
zeros_liker   r   )Drx   r@   rA   rB   rC   rD   rE   ra   r1   r2   r-   r.   r/   r   r   rb   rg   r0   rh   ri   r4   r5   r:   r;   rj   rk   r9   rv   batchchannelsframesr   r   r6   r7   r8   r   r   r   r   guidegrid_size_hgrid_size_wbase_tile_heightbase_tile_widthfinal_outputweightsr   r   r|   rz   r}   r{   r   r   r   r   r   r   r   r   r   r   r   out_temporalr~   r   out_latentssD                                                                       r)   rs   LTXVLoopingSampler.sample  s   < )$w 3 3 @ @AAGOO$)p  29.x'' 	C-/B 03DD+/@@ZZ
 $ B B!3!
  ==' &): :Q >	 > 
 %)$M$M!2200&&*	%
! 	+,E+FGH+**(00Q7..00! +  Bq!  "&#/,Y7Ea EKKN2cbc2 a 5;;q>1Q6MM!$u{{1~5:r rr; "--*ekk!n<K!--*ekk!n<K'7'9'G'G(+{(($ nq(O;; %)_<<
  ~&A+,@A//AB
 +a// /159  >A-- "22F;  $go"W_
7s&1EFgYawb	5'KLQzl;< ..,30&'& (/",  )!-)=0K#1.G-E +)#1%5)  #1'9%53Q(;%5!- 7B 8CII!LL5U4S&7'9(;*?'9%5'#,  +#!!  $(#@#@# $   '#3I#>#D#DQ#GL#(;; $&~~%mm$L $..|<G  0	:==l>Q>QR#;; &&$"# '' &&	  Q1gemWU]BC </C 1a=>,N>G - 'N $w~6 ,/
~r(   r   )N)Nr_   NNr_   Nr   rW   rf   Nrf   )r   r   r   r   classmethodrp   RETURN_TYPESRETURN_NAMESFUNCTIONCATEGORYr   r   r   r+   r>   r   r   r   r   r   r   r   rs   r'   r   r(   r)   rG   rG   @   s    
 c
 c
J L'LHH-6
pU U  (U  "	U n@
&@
 QU".Fr "!%(,),(,$'%)!7ur(   MultiPromptProviderc                   :    \ rS rSr\S 5       rSrSrSrSr	S r
Srg	)
r!  i  c                 $    SSSSSS.4SSS04S	.0$ )
Nrl   re   TzPrompts to encode, one per line. Each prompt will be encoded separately. Each prompt will be used in one temporal_tile in LTXVLoopingSampler.)	multilinedynamicPromptsrM   CLIPrM   z!CLIP model to encode the prompts.)promptsclipr   rn   s    r)   rp   MultiPromptProvider.INPUT_TYPES  s?     %)*. $s  )-P!QR

 	
r(   )rd   )conditioningsget_prompt_listpromptc                     UR                  S5      nU Vs/ s H  oDR                  5       PM     nnU Vs/ s H#  nUR                  UR                  U5      5      PM%     nnU4$ s  snf s  snf )N|)r   r   encode_from_tokens_scheduledtokenize)rx   r'  r(  prompt_listr,  encoded_prompt_lists         r)   r+  #MultiPromptProvider.get_prompt_list  st    mmC(4?@K&||~K@ &
% --dmmF.CD% 	 
 $%% A
s
   A$*A)r   N)r   r   r   r   r  rp   r  r  r  r   r+  r'   r   r(   r)   r!  r!    s1    
 
 
 %L%L HH&r(   )r   dataclassesr   r  r#   easy_samplersr   r   r   ra   r   r	   nodes_registryr
   r   r+   r>   rG   r!  r   r(   r)   <module>r7     s     !   S S 8 &   $   (    	f ffR 	& &&r(   