Add encode --verify & --fail-fast to catch damaged results - #378
Merged
Conversation
alexheretic
reviewed
Aug 16, 2026
alexheretic
reviewed
Aug 16, 2026
| /// Allowed difference between the input duration & the output duration. | ||
| /// | ||
| /// Encoders may round the final frame duration, so an exact match can't be required. | ||
| const DURATION_TOLERANCE: Duration = Duration::from_secs(2); |
Owner
There was a problem hiding this comment.
We should document this in the --verify docs.
alexheretic
reviewed
Aug 16, 2026
alexheretic
reviewed
Aug 16, 2026
alexheretic
reviewed
Aug 16, 2026
alexheretic
reviewed
Aug 16, 2026
alexheretic
reviewed
Aug 16, 2026
alexheretic
reviewed
Aug 16, 2026
Owner
|
Thanks for the pr! I've left some comments. Overall looks pretty good to me, I don't see much in the way of merging this. |
ffmpeg can exit successfully having written a result that is damaged or cut short, usually because the input itself is damaged. Sample based VMAF does not notice this when the samples land on healthy parts of the file. --verify decodes the finished encode before it is moved into place and fails on decode errors, a duration mismatch with the input or missing audio. The input comparisons are skipped when the encode is customised with args that may legitimately change the result. --fail-fast passes ffmpeg -xerror to the encode, so a decode error in the input stops it rather than leaving a damaged result behind.
Drop the matches_input heuristic that silently skipped checks for customised encodes. Each check is now explicit and deterministic, --verify enables both. The audio stream check is removed, there was no evidence of ffmpeg ever dropping it. Move the decode pass into the ffmpeg module, show verify as the last third of the encode progress bar and document the 2s duration tolerance.
pawelkwaczynski
force-pushed
the
verify-output
branch
from
August 20, 2026 19:48
32fdd1d to
4403945
Compare
Contributor
Author
|
Thanks for the review, all addressed in the follow-up commit (rebased on main):
Sanity check on a faststart mp4 with the tail of |
Owner
|
Nice one, thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #376.
Two opt-in checks on the final encode, both off by default.
--verifydecodes the temporary output in full before it is renamed into place, so a failed check leaves no output file. It fails on ffmpeg decode errors, on a duration mismatch with the input, or if the input had audio and the result does not.--fail-fastpasses ffmpeg-xerrorto the encode, so a decode error in the input stops it instead of producing a damaged result.They catch different failures. A source whose container claims 20s while the stream actually ends at 10s re-encodes "successfully" into a 10s file:
--verifycatches that on the duration check, and so does--fail-fast. A source with corrupt macroblocks in the middle produces a full length result that decodes cleanly, and only--fail-fastcatches that one.--verifyin turn covers damage introduced after decoding, which fail-fast cannot see.A few notes on the details:
-xerrorrather than parsing its log output.--vfilter,--enc,--enc-input,--acodecor--video-only, since the result is then not expected to match the input.--fail-fastapplies to the final encode, not to sample encodes.Nothing changes unless a flag is set. Tested on generated fixtures (truncated faststart mp4, byte flipped mp4) and on healthy inputs with audio, with subtitles, with attachments, raw h264 and still images.
cargo test,cargo fmt --checkandcargo clippyare clean.