Releases: Booyaka101/scanverdict
Release list
scanverdict 1.1.1
A bugfix release. 1.1.0 had only ever been tested against ffmpeg's own synthetic sources, so I put it through 156 real video files. It found two false positives, both of which were reaching users.
A sharp progressive file could be called field_blended and told to run srestore in VapourSynth. Its combing floor sat in the dead band between the clean and dirty thresholds, so it had no clean frames without having dirty ones either. The blend rate half of the gate turned out to discriminate nothing at all: the genuinely blended fixture sits at 0.50 and the false positive at 0.90, because slow motion solves as a blend of its neighbours whether or not anything was mixed. The gate now also requires most frames to be outright dirty.
Blend cycle detection reported a cycle on anything with a drifting residual. The autocorrelation was normalised by the whole series energy while summing only the overlapping terms, so the score decayed with the lag on its own and the highest one was always the shortest lag searched. Two files in the survey came back as 52.5 and 21 fps sources that way. Each lag is now normalised by the energy it actually overlaps, a peak has to stand clear of the trend around it rather than just be high, and a peak at a multiple of a shorter strong cycle is rejected as its harmonic. Over cached residuals from real footage, false positives fell from 32 to 16 in 167 windows and recall went from 3 to 4 in 19.
The README now says what the detector did on real material instead of claiming it has only seen synthetic sources. Short version: it works on long steady takes and it does not work on heavily cut footage, where it reads the content rather than the cadence. The file level agreement rule is what stops that reaching you. An obvious fix, dividing the residual by a median filtered envelope to take the motion out, made things strictly worse at every window size tried, so it is documented as a dead end rather than quietly dropped.
The exe
scanverdict.exe is built by GitHub Actions on a windows-latest runner from this tag, not on my machine, and carries a build attestation. You can check it yourself:
gh attestation verify scanverdict.exe --repo Booyaka101/scanverdict
That ties the binary to the workflow run and the commit without anyone having to trust my machine or a checksum I paste in by hand.
It is not code signed, so the first time you run it Windows shows a blue "Windows protected your PC" box with only a Don't run button. Click More info and then Run anyway. A signing certificate costs a few hundred a year and this is a free tool, so that box is not going away.
Needs ffmpeg and ffprobe on PATH. pip install scanverdict if you would rather have it as a Python package.
scanverdict 1.1.0
First public release. 1.0.0 is in the history but was never published, so everything is new
if you are arriving now.
scanverdict decodes real pixels and tells you which of six things a video file is, hands you
the ffmpeg chain that fixes it, then runs that chain and measures whether combing actually
went down and the frame count landed where the cadence says it should.
verdict: telecine_3_2 (confidence high)
container says: progressive (disagrees)
cadence: 3:2, phase 2, consistent across 4/4 windows
verified: combed blocks 238 -> 4 (-98.3%), 29.97 -> 23.976 fps, frame count 360 -> 288 as expected for 3:2
pipx install scanverdict, or grab scanverdict.exe below if you would rather not have
Python at all. One file, no installer. You still need ffmpeg and ffprobe on PATH, on any
route in.
The exe is not signed, so the first time you run it Windows puts up a blue "Windows
protected your PC" box that only offers a Don't run button. Click More info, then Run
anyway. A certificate costs a few hundred a year and this is free, so that box is staying.
The sha256 is 2ffb96ce42817cc64c03ff0df66b37af3f5b2d7b7409279f3a6bf7aba4a6f280 if you want
to check the download landed intact, though it was built on my machine so it only proves
the bytes match what I uploaded.
What changed since the unpublished 1.0.0
--full scans the whole file in back-to-back windows instead of sampling twelve spans of
it. A spliced file comes back as 0.0 - 20.0 telecine_3_2 and 20.0 - 40.0 interlaced_tff
with a numbered ffmpeg cut list, rather than a per-window table you have to read yourself.
Blended frame rate conversions are detected and named. 1.0.0 called a 24 to 25 blend
progressive and admitted it in its own limitations section. The three-frame least-squares
fit only catches a frame mixed from its immediate neighbours, and a 24 to 25 conversion
mixes each output frame from a different pair, so it leaves a repeating cycle in the fit
residual instead. Autocorrelating the residual finds the cycle, which gives you the source
rate and the right srestore frate. This has only ever been tried on synthetic material and
the README says so plainly.
Windows are classified as they are decoded rather than all decoded first, so memory stays
flat in the window count. Without that, --full on a feature length file would have wanted
tens of gigabytes.
Smaller fixes: a filename outside the Windows ANSI code page no longer ends the run with a
UnicodeEncodeError, a closed pipe exits quietly instead of printing a traceback, and a span
that decodes no frames names the file and the timestamp it failed at.
CI is green on Python 3.11, 3.12 and 3.13. The exe was built on Windows 11 and is Windows
only; macOS and Linux go through pipx or pip.