* Build: use craft-media for bitstream, isobmff and matroska
filmcraft-bitstream, filmcraft-isobmff and filmcraft-matroska re-export
craft_media::{bitstream, isobmff, matroska} from craft-libs. The packages
and their public paths stay, so dependent crates build unchanged. The
integration tests in crates/isobmff/tests and crates/matroska/tests run
against the re-exports.
* Build: pin craft-media at 9db732e
craft-media spells the Matroska colour types in US English: Colour is
Color and VideoInfo::colour is VideoInfo::color. The spec names
element_ids::COLOUR, COLOUR_SPACE and VpcConfig::colour_primaries stay.
* matroska: the oracle skips the duration of a track's last frame
Ported from craft-media: the last audio or video frame of a track cut by
-t is shorter than a codec frame. ffmpeg 8 writes a shortened
BlockDuration and reports the codec frame duration; a remux by our writer
stores DefaultDuration and ffprobe reports the shortened one. Subtitle
cue durations are still compared. This fixes oracle::mjpeg_ac3 with
ffmpeg 8. The HDR test is named hevc_hdr_color, as in craft-media.
* matroska: laced_remux laces every audio track and checks timestamps
craft-media laces only tracks with a DefaultDuration. The remux gives
each audio track without one its mean packet spacing, so Vorbis, FLAC
and PCM lace too, and compares every packet's timestamp with the
source's. Ported from craft-media's oracle_matroska.rs.
* codecs: the Matroska audio timing test laces its Xiph case
craft-media laces only tracks with a DefaultDuration. The test's
Matroska helper sets the AAC access unit's duration (1024 samples,
rounded to the nanosecond), and the test checks that the Xiph-laced file
has laced blocks and the unlaced one has none.
* Build: repin craft-media to f97c84d27 (NAL length-size checks)
craft-libs#245 is on storytold/craft-libs main, so the dependency points there.
* Build: repin craft-media to f0ad6c1e1 (QuickTime v2 PCM entry limits)
ci.yml calls the shared workflow (cached apt packages, nextest, main-only cache saves, Cargo.lock check). FreeBSD and Windows ARM64 run nightly and on pushes to release instead of on pull requests. Depends on storytold/craft-common-actions#69.
* Packaging: pin the Windows signing client and check its hash
* Packaging: pin appimagetool and check its hash
* Packaging: an architecture without a pinned appimagetool hash fails early
* Packaging: pin the AppImage runtime (type2-runtime 20251108) and pass it with --runtime-file
* Packaging: assign the empty hashes with '' (shellcheck SC1007)
* Fonts: pin craft-fonts bfcbf71; CRAFT_FONTS_REQUIRED fails without CRAFT_FONTS_DIR
craft-fonts main adds Noto Sans CJK SC, Noto Sans Arabic, Noto Sans Thai and
Noto Sans Georgian. FilmCraft registers every CRAFT_FONTS entry, so releases
pick them up with the pin bump. ATTRIBUTION.md and NOTICE list them.
With CRAFT_FONTS_REQUIRED set, crates/text/build.rs errors when
CRAFT_FONTS_DIR is unset or empty, not only when it is not a checkout.
Refs storytold/craft-libs#197
* Fonts: only CRAFT_FONTS_REQUIRED=1 enables required mode
* text: the CRAFT_FONTS_REQUIRED message says unset or empty
* fix(engine): use resolve_absolute for stored media paths
* fix(engine): give the reason when a scratch disk folder is refused
* CI: check that git dependencies come from storytold
* CI: release only with git dependencies from storytold
* doc_path: a foreign drive path without a document is refused, not document-relative
* Workflows: one Git-source check: lockfile present and current, no source replacement, storytold hosts only
* Workflows: the Git-source check reads the legacy .cargo/config too
* Workflows: the Git-source check parses cargo config with tomllib
* Tests: one integration-test binary per crate
Each crate with several tests/*.rs files keeps them as modules of tests/it/,
so cargo links one test executable per crate instead of one per file. Files
that change process-wide state or time a workload stay binaries of their own.
* Profiles: line tables for workspace crates, no debug info for dependencies
* Windows ARM64: nightly and on release pushes instead of every push to main
* xtask ci: clippy and tests in the dev profile
The release profile's thin LTO and single codegen unit made linking the test
binaries take most of the gate. The codec and audio crates stay at opt-level 3
in the dev profile, so their tests run at release speed.
* xtask ci: nextest, doctests, no examples, one wasm check
Tests run with cargo nextest when it is installed (cargo test otherwise) and
build with --lib --bins --tests, so examples aren't linked; doctests run
separately. The wasm check keeps going past the first failing crate. VP8
fixture generation locks across processes, since nextest runs each test in
its own.
* VP9 synthetic fixtures: write aside and rename
A test in another process could read a fixture ffmpeg was still writing.
* Fuzz tests: a third of each sweep by default, all of it with FILMCRAFT_FUZZ_ITERS
Every seed, mutation kind and thread count still runs. Header bytes each get
one overwrite value and two bit flips in rotation, so every value and bit
index still occurs across the region. FILMCRAFT_FUZZ_ITERS=N runs the whole
sweep plus N random rounds per seed, as before.
* Platform fallback tests: one failure point per hybrid path
The failure-anywhere test injected a failure at four points around every
restart point; the hybrid's paths differ only in the first GOP, around the
second and last restart points, at the end and never. The replay test needs
the first two GOPs.
* Export tests: shorter ranges with the same checks
The bitrate test measures 0.5–1.5 s, where each preset reaches its own
target (on 0–3 s the simple demo left two presets at the same rate). The
every-preset test exports three frames per preset.
* Audio tests: effects in parallel, a table-driven FFT for the Opus quality metric
The extreme-settings test keeps both settings and the 40 s tail for every
effect, one thread each. The Opus quality metric's FFT builds its twiddles
once and allocates nothing per transform (same algorithm and summation order).
* CI: dev-profile gate with nextest
xtask ci no longer builds with --release, so the release-profile overrides
go; nextest is installed for the test step.
* CI: apt packages through the cached install-apt-packages action
* Review fixes: fuzz tests with a panic hook in their own binaries, loud fixture lock
The fuzz tests of av1, h264, hevc, mpeg2v, vp8 and vp9 count panics through
a process-wide hook, so a panic in another test of the same process would
fail them; they are binaries of their own again. The VP8 fixture lock fails
the test instead of skipping it silently, and the full-sweep doc comments say
how many truncation points the full run samples.
* Fuzz tests: rotate the default subset per run (FILMCRAFT_FUZZ_SEED replays one)
* platform tests: decode-switch tests in their own binaries, one NVENC lock