Skip to content

v4.2.0 - Cut with --fill-held off kept as cycle.source/ beside filled loops so alignment needs no clip frames, with cycle_source in the loop report (video-loop, video-cycle-align)

Choose a tag to compare

@aldegad aldegad released this 07 Nov 05:02
· 7 commits to main since this release

Upgrading from 4.1.0: loops with no held cell made and cuts with --fill-held off give the same files byte for byte as 4.1.0 except the report's producer.implementation_sha256 (four of seven cuts measured before and after: a synthetic walk with a held frame cut with --fill-held off, a synthetic walk with nothing held, and the application's walk flags on a synthetic strider with the fill off and with the fill on where its fill made no cell); cuts that are not loops (played once or an effect's lifetime) and cuts with --out-fps were not measured and are unchanged because the new step does not run for them. For a loop at the clip's rate whose held cells were made again, the delivered cycle/, <name>.strip.png, <name>.strip.json, <name>.gif, and <name>.webp are byte for byte as in 4.1.0 and the report differs only in cycle_source and producer.implementation_sha256 (the other three measured cuts: the held walk, the same with jump repair on, and a walk whose last cells were held), while video-loop now cuts the clip's frames a second time with --fill-held off to keep cycle.source/ beside it (0.31 to 0.40 times the loop's output size on test walks, 19.0 to 19.8 KB beside 48 to 64 KB; cut time 0.41 s to 0.75 s on the synthetic walk and 0.83 s to 1.63 s with jump repair on; 14 RIFE binary calls instead of 12 on an Apple GPU on rife-v4.25 and rife-v4.6 where the second cut repairs a ghost), adds cycle_source to the loop report and summary JSON, and writes stderr lines around the second cut. An app that cuts in one place and runs video-cycle-align in another must carry cycle.source/ with each loop's cycle frames, strip, strip record, and report so alignment needs no clip frames; loops cut by 4.1.0 or earlier have no cycle.source/ and align as before.

  • New: video-loop keeps the cut with --fill-held off beside a filled loop as cycle.source/. When a cut is a loop at the clip's rate (no --out-fps) and its held cells were made again (held_fill.made or held_fill.again.made), once the filled cut has passed every gate and its GIF and WebP are written video-loop cuts the clip's frames again with --fill-held off from the report's cut_args and frames_dir through loop.cut_again. It builds the cut in .cycle.source.cut/ beside the loop; if it takes the same clip frames (cycle_drawings start and length), its frames, <name>.strip.png, and <name>.strip.json are put in place as cycle.source/ by one rename and .cycle.source.cut/ is removed. Stderr prints video-loop: <name>: its held cells were made again, so it is cut again with the fill off and that cut is kept as cycle.source/ for video-cycle-align; the lines below until it is kept are that cut's before the second cut's lines and video-loop: <name>: the cut with the fill off is kept as cycle.source/ after; if the second cut fails or takes other frames, stderr prints video-loop: warning: <name>: its held cells were made again and no cut with the fill off is kept beside it (<reason>): video-cycle-align cuts it again from the clip's frames, or stops on it without them and the filled loop is still delivered.
  • Fix: video-cycle-align aligns filled loops from cycle.source/ without needing the clip's frames. Up to 4.1.0, aligning a loop whose held cells video-loop made again always re-cut the clip's frames with --fill-held off, stopping when a set was aligned away from those frames. Where cycle.source/ beside a loop holds a strip record showing no cell was made, video-cycle-align now aligns from it directly and cuts nothing, giving byte for byte the same cycle frames, strip, GIF, WebP, and cycle.source/ as aligning from the clip's frames, and the same strip record except cycle_align.cut_again (written only when the alignment itself cuts again). Only where cycle.source/ is absent (a 4.1.0 or earlier loop, a failed second cut, or a folder not carried along) does it cut again from the clip's frames or stop without them, saying to carry the cycle.source/ video-loop kept beside it (its cut with the fill off) or cut it again with video-loop --fill-held off and align that.
  • The loop report and printed summary JSON record cycle_source when a loop's held cells were made again at the clip's rate: kept (true), dir ("cycle.source"), fill_held ("off"), cells (cells of the cut with the fill off), and made_before (held_fill.made), or kept (false) and why when no cut with the fill off is kept. Loops with no cell made and cuts with --fill-held off record no cycle_source.
  • Python callers: sprite_gen.video.loop: new keep_unfilled(report, out_dir, name, cut, **asked) (the cut again with the fill off kept as cycle.source/; ValueError naming why it is not), new filled(meta) and CUT_AGAIN_DIR (both moved from align); sprite_gen.video.align.filled and align.CUT_AGAIN_DIR keep their names and refer to those; align.unfilled_source aligns from a kept cut and otherwise calls keep_unfilled.
  • Docs: loop-repair.md section 7 ("An alignment: aligned as filmed, filled at the end") and section 4 ("The cut as filmed is kept"); video-pipeline.md section 4 (held cells, and what a refusal removes); --fill-held help of video-loop and video-cycle-align.
  • Tests: tests/video/test_no_repeat_default.py adds test_a_set_with_a_filled_direction_is_aligned_without_the_clip_s_frames_as_it_is_with_them, test_video_loop_keeps_a_filled_loop_s_cut_with_the_fill_off_beside_it_and_an_unfilled_one_s_as_it_was, and test_a_filled_loop_whose_cut_with_the_fill_off_fails_is_delivered_and_says_why_nothing_is_kept, and removes cycle.source/ first in two existing alignment tests (covering 4.1.0 loops and the updated stop message); tests/video/test_loop_prop_seam_held.py checks cycle_source on the loop report and no cycle_align.cut_again on the aligned strip record; tests/video/test_ghost_given_way.py moves the RIFE binary call pin on the synthetic strider from rife-v4.25 10 to 12 and rife-v4.6 12 to rife-v4.25 12 to 14 and rife-v4.6 14 (the test's pin per model holds on every machine, including the Linux llvmpipe lane; its new values were measured on an Apple GPU, where the app walk ran the binary 12 times at 4.1.0 and 14 times now on both rife-v4.25 and rife-v4.6; 17 call-pin tests run, none of the others moved).

Install or update:

pip install --upgrade "sprite-gen @ git+https://github.com/aldegad/sprite-gen.git@v4.2.0"

The wheel, the source archive and SHA256SUMS are attached. Full notes in CHANGELOG.md.