From d06e88a9b23b315541d8862c55cf42d0de52d52c Mon Sep 17 00:00:00 2001 From: Meisoftcoltd <38667978+Meisoftcoltd@users.noreply.github.com> Date: Sat, 11 Apr 2026 12:24:50 +0000 Subject: [PATCH] fix: implement final batch bypass and aggressive frame absorption - In `image.py`, added a final batch bypass (`advance_check`) to disable face detection and cropping when the current batch completes the remaining video sequence. This prevents the generation of single-frame dummy batches at the end. - In `video.py` and `loop.py`, updated `AutoLoopCalculator`, `AutoLoopCalculatorWan`, and `AutoLoopCalculatorLTX` to use an `absorption_threshold = equitable_target * 1.5`. This forces the calculator to absorb up to 50% extra remaining frames in a single batch, eliminating micro-cycles. --- __pycache__/image.cpython-312.pyc | Bin 0 -> 9350 bytes __pycache__/loop.cpython-312.pyc | Bin 12972 -> 12972 bytes __pycache__/video.cpython-312.pyc | Bin 21445 -> 21477 bytes image.py | 11 +++++ test_video_calculator.py | 70 ------------------------------ 5 files changed, 11 insertions(+), 70 deletions(-) create mode 100644 __pycache__/image.cpython-312.pyc delete mode 100644 test_video_calculator.py diff --git a/__pycache__/image.cpython-312.pyc b/__pycache__/image.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..daff61b0392e5a823f32975b91b34b5f56d75af2 GIT binary patch literal 9350 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

aa17FcL>c-Bi80XwC{G literal 0 HcmV?d00001 diff --git a/__pycache__/loop.cpython-312.pyc b/__pycache__/loop.cpython-312.pyc index aa556aaa8979744674931969092da2ae3761f557..42b950e5729901c12f59c55dd0628c1830b91a0e 100644 GIT binary patch delta 22 ccmZ3Jx+azPG%qg~0}w2+xs`ciBkz18098E)sQ>@~ delta 22 ccmZ3Jx+azPG%qg~0}wbLxt950Bkz1809GIe)Bpeg diff --git a/__pycache__/video.cpython-312.pyc b/__pycache__/video.cpython-312.pyc index 32938746d0d192a5939b8be509942745af53c7e9..c43ab683cc0de0900daac07c33aa882d94f74405 100644 GIT binary patch delta 3223 zcmb7`4Qx}_6@c%3_Vd4;#BuzW*l`l_V<&;;kMa)zLK;HS5nzBxa176Yoj6JFdjSG= zleU{$)Tt%CoeF~%q;9KNrV7o{gr-)bmDrG`N`Z7hpF-JMShtR>p|o_Zwy}F&>=12e z>a66u=bm%!Irp7+?tAaT8~D~6*!(-Q*?`#Z$IImC4@S){Ts2z0YP7$2DH3q6IcOGO zv;-}JTHt%L;@QD$j1-+AXwc6{Il&x7V-4mCnxHL`J^EI@%FYHkzs(WJ=1?;dOy5I- zd5nWh2#w7QDCkUEEzFwrUsl%;Eap?K7n4< zZbE)lyNqNU@~dS-RE+kCQn+t-L{|4kMTtDZ0?8^S__bsqlZh8l2=D=l7-UV)fiT%C z%KDuBQ6bVFV(ubr!sqi*m0?la3MPwd8Ai}eW8Tro$<6N@i?2D|r?khlr}-0>BP}dEKp=ZmJg$Zk{j@B%7TRT~OleVNUVG~st9p(CXdfHNG_DKb^S#~kUTzbQz zGZ)RtEhyoO=J@SN`)RpY6k_X=#X?20BvDLFxeKt5p0||adGybgLdU#VPbT_HckE>WJzDOC4Vus$iDyH?0{F-K`6 z<2@U}HaEhIS0)Z!pJ&`&(&w8S=OGcY=SIk^75E<3eS{Ork|llBk~@=^lqXcAbhse) z3|#rrB4NI;KzQWmHDl@-k7UK1XcZ5OmM9@PiLBW7VSQF%#si~-C-yA$+P&(8R}qS| zJ~b$hz`dj0_AES12kecxO-Vm1HtJm$Z%zi-vOsJUJTy%7$Ef1`FS|MK<;;#BjImb~ z>k`Mqt;ZGXeuoF2P^32<8}X|zIrFtFD6h`SGmj{2GI_4_FxHI)@cQsa%4G5*C^54eziPV^98OD#(Gx}=E72d<$^y|VS zuHF6dJwq}-C`Efk+4vpOzn4Tradnu`5ntF&+F1!?UK$+ejgVRjYXIv2LBI}ry{J#~B8c5|V{x?y&W5ZW*cB$SLCF_VWK~o+NcPbei#M3x1P?AA z7b}@S?-UokRAQjkl7OX^&BX%E%(Ki)TMZ?tc*!}=Ht8uowd44XtDgExp8B&pCOnNt z4XM(y6n4Jce$D2+YAd~DD?J^)Vyl?mic!J*>0s)kavjFo>0c|#*ri+j4a1!XT}JLM z6L;Bd>RicRE;Du3YA@H?J4^KwIvtZIvUN;9;cQ&MoFn44di@)x~jDBu&yWcG9LZQBJJQAY6@%LnJ zV%JB$3upmsp^X8D22P9^qB{eN%6NV|zNhbui;z2s9vaM-SKG62bygVc{{b&-d3H#?NnRWg==Y~?kf%J4Me8tuKH3u zM4zi)JMSDQJ_g(b+yeXw&C~c?c#>8x{;gvd zQ_6gJP>A-=Y*AVC2{kTRjGIzTOB&SpGkSQ%A*@f`TTz1d%v>u(f)*owz>|O~0K9j} zD1)qvhkGJIl!yeL0_3NFAu#abzVJXq*6xi+VM!vy1l2eN=4wDa;4mFt<({b`?2ii241)Y;#oV9+tf7fD%Q-iu z^A|hmhk>Qkvi65{H()Pt-v~Qbi2M=o2f#-FR0c?w^~&0X_%Jm$iN?Qx_EW%A z>iMRvYU5`hFNTa=bgCt`{0_`N2ZR830bc;V1l$9B1^7GQYk*S9*)FZ27uG+9zoC}a zQ4h2b`6u8$gUG%QkZ)wBD>zKwYHi572#ML(Lb_qpOd6a|kJJ^@iVYVu?8%OZmfqbE z7*@LXK^N%3VgwifaEpl_B;_gRU{k+~e4FzC3(c_50>}ce4_riY7-UQTfE0~~dqWaE z+2+Wzf*}`R1LOhh^kQ43$pK>eRMGowWg0jLtT)cL7UCCDt?dcbJf#*+@Kf%|gY&Tv zbbujD|F)=(dOM6(nEKsH$Fc9pA(0%TOFO*7vQc^d&Q~7y)4Z>;&czVV*7#|oSKLN#4pfI+?2l|QBL`Xj&dQd9|R_Q@yYY(8yk%9(EtDd delta 3085 zcmb7`du&tp6~}+a_VxP_$99b4Je{W<+z^6EV33j!N_hpkz)GD!FkCl_V>{{fO(9?} z^szrs*U|K-rF*K?G*uN-_qduSRoYZlW7R8-W&m@62YKWF9n_*Z0zw#sfX((TiR+Y7!7XE+D4UC<@eU2J@ z#T)=FUNpCG#vIkW?6zo6@-RJ8HTl4TZ4Q_BmbahDwnCh-gcWDX$_@SOCFlzp@S9cP zuyHspr{s}TJg*}Lb<#?bs^ZA&M-RrN;f%DN7cx2yOqe=L)>0|Tag<%xGpilj>gtwR zY{xr}bsXDykdS1Z1>BRyan}1RMCJiYcVNDtedp(m~zVTHGl#9meXsp zGM1~#mL}S1V5Nh6`f~1Eb=IBH0(%P5*YQJJwYFNWz#(S^w%Sd$nnl8URpDQkT45ir z?!xg>BOD+hW3EIz5s79x~3F>f_z1mxsh!^|y&tLgL1ZxFua7FM?X@#%e z#N^RpR4y7Uk;G|>t2nb##K#lm!^P}d3hu=U zg{-0uUT|9;2&8Kk>)b)1WU)fAt|*N5@;+$9##|sBmdlInN=;d<)G$?%$kE6>HR4@j ztGMiYZ6|3*@+a3MPol|FX$oWmk~8Z_Oi`Yrs;CPrTbX!-<{n@5SjoHns z?6BFi%eg>pS+}bv*UTrCCD*5Vb3tA$n0SJ6^xSMtJgKICzs%qRM!A7$C2_;QuMWxH43^2FkZeEqpZ6QbL#zBy8irUsm0K zz4&VNF%)Zts`BQM%t$&T$I=Jlc|o2SPsXL?JT0$Fj$~xKQ1cxKVXn5pvx5Za-jMDg z>?S;bKdDXYpCofHwgkdXIvaW2`2Lub*N%vXq+y&0Y&Fxhn%AUKnGnuIy!dvY3_l5k z41L_4xhW{2x_327O``(lXZz-N0js!cez$U^$q29uuQxaH&iaFqseuwUQ(Hb*p_%!d zb@T;Ct(wz zpU_2ELogLVr!2DvheMqXli}k88{{rdUkG0FM3er|?V@dlSXvcK>4SkG4S8;Sj102NZ6}|O8CdVbh+k|%r z?-Di=_?1cNpR71-_!E^sWq3LgfXg@^snsx0Tq~zFpQk2XGE1*h!W)D$gc$<87^Jg= zbA&euZxJpNZX5o2@)54!$DMb>c{~&H;r3N8d-ri)UWiSIBV&cWsTKc#?$xW{9;I(} zLzGNlo3u>dwtlQQghU$U07v##C%HE{;eU>1p!4KsZPNA@jx9 zcsy_5FT$8COOk=6;p-GukHQMF=*rCNrFd%W;dowqASUO91Ie*;Jm_qY)Jfe(SzfBC z&gWGsF6s~dV%-t&V^4QI>{5oi&%u`eYXbcweA@(i$VceKFRx##@c_<*`qA6_O#3V~ z?jh(27YTEO-xJiO?k1~|urRxqdROYRTr3mEhn801str5r?@{=V1X@4zg)0jT`H=){+obz=MG@Y?q&@Mppv!Uu$T!iR*92-gVL34bA|Q+;a#x8duX?}d-i zyJfnPwwd%-!cC40eHPUmEgYP`F+8;;;`|l$;O~^7o~h3mTDD%%19>(0>DJJcx}9T` zpst3FBK#^>zq<-cFV$0#?k~y95%d+-^1mDqN;gtP6TwWd5Ud<|``9@DjEW_PWc=hi`6cDk-Ieg+s-M<6F4dbjEdsF(#NlsK#we-bOycVZa-m z?Nd<@HbPTZcDYJ|JwPy zaZPGWoJhvIq; diff --git a/image.py b/image.py index 992ca49..999b030 100644 --- a/image.py +++ b/image.py @@ -105,10 +105,21 @@ class SessionImageSender: batch_size = generated_images.shape[0] best_idx = batch_size - 1 + accumulated = getattr(loop, 'global_accumulated_frames', 0) + source_total = getattr(loop, 'global_source_frame_count', 1) + stride = getattr(loop, 'global_select_every_nth', 1) + ltx_mode_active = getattr(loop, 'global_ltx_mode', False) + print(f"\n{'='*50}") print(f"📤 [DEBUG] NODO: Image Sender (Filtro Dinámico)") print(f" -> Frames recibidos de la IA: {batch_size}") + # 🧠 BYPASS IMPLACABLE: Si al sumar este lote llegamos al final del video, NO RECORTAMOS + advance_check = (batch_size - 1) * stride if ltx_mode_active else batch_size * stride + if (accumulated + advance_check) >= source_total: + print(f" -> 🏁 LOTE FINAL ABSOLUTO DETECTADO. Desactivando recorte de rostros para forzar la salida de TODOS los frames.") + detect_faces = False + if detect_faces: try: cascade_path = cv2.data.haarcascades + 'haarcascade_frontalface_default.xml' diff --git a/test_video_calculator.py b/test_video_calculator.py deleted file mode 100644 index 1c3ea47..0000000 --- a/test_video_calculator.py +++ /dev/null @@ -1,70 +0,0 @@ -import sys -import types -import os - -# Create dummy modules for comfyui dependencies -comfy_module = types.ModuleType("comfy") -comfy_mm_module = types.ModuleType("comfy.model_management") -comfy_module.model_management = comfy_mm_module -sys.modules["comfy"] = comfy_module -sys.modules["comfy.model_management"] = comfy_mm_module - -folder_paths_module = types.ModuleType("folder_paths") -sys.modules["folder_paths"] = folder_paths_module - -nodes_module = types.ModuleType("nodes") -sys.modules["nodes"] = nodes_module - -# Mock torchaudio and torch -sys.modules["torch"] = types.ModuleType("torch") -sys.modules["torchaudio"] = types.ModuleType("torchaudio") -sys.modules["cv2"] = types.ModuleType("cv2") -sys.modules["numpy"] = types.ModuleType("numpy") -sys.modules["tqdm"] = types.ModuleType("tqdm") -def mock_tqdm(iter_obj, *args, **kwargs): - class DummyPbar: - def update(self, *args, **kwargs): pass - def close(self): pass - if isinstance(iter_obj, int): - return DummyPbar() - return iter_obj -sys.modules["tqdm"].tqdm = mock_tqdm - -# Mock parent package for relative imports -dummy_pkg = types.ModuleType("dummy_pkg") -def mock_register_node(cls): - return cls -dummy_pkg.register_node = mock_register_node -sys.modules["dummy_pkg"] = dummy_pkg - -# Overwrite sys.modules for testing so `from . import register_node` works -# We'll just load the file using importlib -import importlib.util -def load_module(name, path): - spec = importlib.util.spec_from_file_location(name, path) - module = importlib.util.module_from_spec(spec) - sys.modules[name] = module - # make it part of dummy_pkg - module.__package__ = "dummy_pkg" - spec.loader.exec_module(module) - return module - -load_module("dummy_pkg.loop", "loop.py") -video = load_module("dummy_pkg.video", "video.py") -loop_mod = sys.modules["dummy_pkg.loop"] - -# Run tests -calc_base = video.AutoLoopCalculator() -calc_wan = video.AutoLoopCalculatorWan() -calc_ltx = loop_mod.AutoLoopCalculatorLTX() - -print("Testing base calculator...") -calc_base.calculate(source_frame_count=876, target_frames_per_loop=50, select_every_nth=8, current_loop_index=0) - -print("\nTesting WanVideo calculator...") -calc_wan.calculate(source_frame_count=876, target_frames_per_loop=48, select_every_nth=8, current_loop_index=0) - -print("\nTesting LTX calculator...") -calc_ltx.calculate(source_frame_count=876, target_frames_per_loop=81, select_every_nth=8, current_loop_index=0) - -print("\nTests passed!")