Skip to content

Releases: ivenos/avet

v1.0.0

Choose a tag to compare

@ivenos ivenos released this 12 Aug 12:49
a5d563e

Added

  • Target quality ([target_quality]) - encode to a perceptual quality floor instead of a fixed CRF. avxs probes each chunk at several CRF values, measures CVVDP (ColorVideoVDP, in JOD) against the source with the bundled FFVship, and keeps the highest CRF that still holds the floor. Interpolated binary search on the encoder's 0.25 CRF grid, with min_probes/max_probes, an above-floor tolerance, min_crf/max_crf and probe_preset. Solved CRFs are cached, so a resume does not re-probe.
  • max_encoded_percent - caps a chunk against its actual source bytes and raises the CRF when holding the floor would blow up the bitrate, logged as a warning.
  • SIGTERM and SIGINT finish the current job and then exit, instead of orphaning the encoder processes onto chunk files the next start writes to as well.
  • A finished file has to hold every frame its chunks account for before it is moved into the output directory.
  • CONTRIBUTING.md and AGENTS.md.

Changed

  • Target quality requires a GPU. CVVDP runs on Vulkan (NVIDIA/AMD/Intel); with only a software Vulkan device or none, the job fails fast with a clear message instead of taking a CPU path that is too slow to be practical. No other pipeline step needs a GPU.
  • Auto-crop is applied before scaling, so content edges stay clean when both are combined.
  • Cached scenes and chunks are discarded when the encode profile changes, so a resumed job never mixes output from different settings.
  • A source still being copied, a full disk, a tool that hit its timeout and a GPU that is not up yet are retried on the next scan instead of writing a marker that locks the file out.
  • The worker count follows the container's own memory limit rather than the host's.
  • Two input files that share a name are both skipped instead of overwriting each other's output.
  • If you were tracking :dev: the [target_quality] key vmaf is now jod (0-10) and the metric is CVVDP. All other keys are unchanged.

Fixed

  • Every job outside the Docker image failed after encoding all of its chunks: the ffmpeg concat list held relative paths, which the demuxer resolves against the list file's own directory.
  • Odd source dimensions (853x480 web rips) desynchronised the Y4M stream feeding the encoder.
  • Auto-crop found no bars in a 10-bit source and invented one on a clean 8-bit source; the black threshold now scales with the bit depth and edges round to even.
  • Dolby Vision profile 5 was encoded with badly wrong colours, and the check meant to catch it never fired. It is now refused with a clear message.
  • Five colour transfer names ffprobe actually reports never reached the encoder.
  • Audio and subtitle tracks tagged und were stripped by a language whitelist, leaving an untagged MP4 rip with no audio at all.
  • An archived source could overwrite an earlier one of the same name in input/processed/.
  • Resume state was not flushed before being renamed into place, and a zero-length state file failed every later run.
  • Switching between svt-av1 and svt-av1-hdr mid-job resumed onto the other encoder's chunks.
  • The Docker image could ship a stale binary while the build reported success.
  • A failure after the output was already in place was reported as a failed job.

Removed

  • VOLUME ["/input", "/output"] from the image: without a bind mount it sent finished encodes into an anonymous volume.
  • docs.md - its content lives in the README.

Dependencies

  • SVT-AV1 v4.1.0 -> v4.2.0
  • SVT-AV1-HDR 1bd66be -> cfb4e17
  • Vship (FFVship) v5.1.0 - new, bundled for CVVDP
  • Rust toolchain 1.96.0 -> 1.97.1 for the image and the AppImage; the MSRV stays 1.95
  • tokio 1.53.1, serde 1.0.229, serde_json 1.0.151, anyhow 1.0.104, toml 1.1.4, av-scenechange 0.24.1
  • walkdir removed, replaced by std read_dir

Full Changelog: v0.4.2...v1.0.0

v.0.4.2

Choose a tag to compare

@ivenos ivenos released this 22 Jun 10:29
c3a871e

Fixed

  • The subtitle probe is now retried instead of aborting the whole job on a transient ffprobe failure, and the real error is logged (it was hidden by -v quiet).
  • A failed job always writes its .failed marker, so it is no longer re-attempted on every poll.

Changed

  • encoder is no longer required when avxs.video = "copy".

Dependencies

  • av-scenechange: 0.23 → 0.24 (#12)

v.0.4.1

Choose a tag to compare

@ivenos ivenos released this 20 Jun 14:08
da748f5

Added

  • [avxs] video = "copy" passes the source video through unchanged and runs only the audio and subtitle steps. The video-only options (hdr, crop, keyint, scale, bit_depth) and [encoder_params] are ignored in this mode; encoder is still required but unused.

Changed

  • Merged duplicate integration tests and gave timed negative tests an early-exit on their expected log line. Faster suite, no scenario dropped.

v0.4.0

Choose a tag to compare

@ivenos ivenos released this 20 Jun 12:41
31c0463

Added

  • Audio bitrate per channel layout: bitrate may be a table keyed by layout (stereo, 5.1, 7.1, ...) with an optional default. The layout is taken from the source automatically.
  • [audio.lossless] block that overrides handling for lossless sources and inherits any unset field from [audio].
  • Automatic lossless vs lossy detection, sourced from ffmpeg's own codec table. DTS counts as lossless only in its Master Audio profile.
  • Per-codec encoder options, e.g. { compression_level = 12 } for FLAC.
  • Re-encoded audio tracks keep their original name with the target codec appended.
  • Audio plan printed before the encode, one line per kept track.

Changed

  • bitrate is no longer required when the target codec is lossless (FLAC/PCM/...).

Fixed

  • Encoding multichannel audio to Opus no longer fails for 5.1(side) and other side/wide layouts; they are remapped to the matching native layout while keeping the channel count.

Dependencies

  • Alpine base image: 3.23 → 3.24 (#10)
  • GitHub Actions: updated to v7 (#11)

v0.3.1

Choose a tag to compare

@ivenos ivenos released this 05 Jun 17:13
dd23d11

Changed

  • svt-av1-hdr is now built from upstream main instead of the v4.1.0 tag. svt-av1-hdr is a rolling-release fork, and its author confirmed main is the recommended source.
  • Container image publishing is now gated on the integration tests - images are only pushed to the registries after the full encode pipeline passes.

Security

  • GitHub Actions workflow permissions tightened to least-privilege; publish jobs opt into elevated scopes only where needed.

Dependencies

  • svt-av1-hdr pinned commit → 1bd66be (#8)
  • Rust toolchain 1.95.0 → 1.96.0 (#7)
  • serde_json 1.0.149 → 1.0.150 (#3)

v0.3.0

Choose a tag to compare

@ivenos ivenos released this 20 May 21:02
5686e96

Added

  • Configurable encoder input bit depth via the new [avxs].bit_depth option. Set to 8 or 10 to force the FFMS2 pipe to convert the source to the chosen depth before the encoder reads it (SVT-AV1 picks up the bit depth from the Y4M header). Omitted = source depth passes through, matching the previous default (8→8, 10→10). Enables 8→10 conversion for slightly better fidelity at ~5% size cost, per SVT-AV1 documentation.

v0.2.1

Choose a tag to compare

@ivenos ivenos released this 18 May 19:05
7424fcd

Fixed

  • Out-of-bounds crash near end of encode on sources where the scene detector and FFMS2 indexer disagree on the total frame count (e.g. remuxes with a broken last GOP). The last chunk's frame range is now clamped to the FFMS2 count, so the encode no longer aborts at 99%.
  • Permanently failed jobs are now detected during the scan instead of after the job startup pipeline - no more redundant indexing before the .failed marker is honored.

v0.2.0

Choose a tag to compare

@ivenos ivenos released this 17 May 18:15
766a331

avxs is now available as a self-contained Linux AppImage for x86_64 and aarch64, in addition to the Docker image. All required tools (ffmpeg, mkvmerge, SVT-AV1, SVT-AV1-HDR, FFMS2) are bundled - drop the AppImage on any modern Linux and run.

Added

  • AppImage distribution for Linux x86_64 and aarch64
  • Track disposition preservation in muxed output - forced subtitles, hearing-impaired flags, default-track markers etc. now survive the pipeline
  • Integration test suite under test/ exercising the full encode pipeline on synthetic fixtures

Changed

  • HDR detection now covers the full ITU-T H.273 color table (4 → 11 primaries, 4 → 16 transfer characteristics, 4 → 13 matrix coefficients) - broader correct tagging for HDR10, HDR10+, Dolby Vision fallback and various broadcast formats
  • AVXS_POLL_INTERVAL=0 is clamped to 1 second to prevent CPU busy-loops
  • lp encoder param now accepts both integer (lp = 8) and string (lp = "8") forms
  • Previously-silent fallbacks (unknown FFMS2 pixel formats, ffprobe non-zero exits, out-of-range subtitle indices) now produce visible warnings

Fixed

  • Resume robustness: truncated chunk files (from disk-full, SIGKILL etc. mid-encode) are now detected and re-encoded instead of being silently reused, preventing corrupt output
  • HLG false-positive warning removed - "HDR metadata incomplete" is no longer logged for HLG content, which has no static metadata by spec
  • Non-UTF8 filenames are skipped with a warning instead of silently colliding on a fallback temp directory name
  • Crop::from_str now strictly requires exactly four colon-separated parts

v0.1.0

Choose a tag to compare

@ivenos ivenos released this 16 May 12:18
9da2bd4

This is the first public release of avxs.

If you run into any issues, please open a GitHub issue so I can look into it.