0.12.0 (July 6, 2026)
This release adds FFmpeg 8 support: a single build now links either FFmpeg 7.x or 8.x, with the bindings gating on the installed version. It fixes the FFmpeg 8 runtime failures reported in #37, ports the FFmpeg 8 fftools behavior changes (global side-data propagation, downmix handling, DTS-interleaved pre-mux flushing), and continues the unsafe-reduction work with RAII owners for the format/filter FFI pointers. CI now tests every change against both FFmpeg majors.
Added
-
FFmpeg 8 Support (7.0 through 8.x)
ffmpeg-next/ffmpeg-sys-nextmove from 7.1 to 8.1.0 — the first upstream line that handles FFmpeg 8 correctly. FFmpeg 7.x remains fully supported: the sys crate probes the installed FFmpeg at build time and gates its bindings on the detected version, so existing 7.x setups keep building unchanged. Breaking: downstreams that unify the re-exportedffmpeg-next/ffmpeg-sys-nexttypes (AVRational,AVMediaType,Frame) with their own 7.x pins must bump those pins to 8.1. -
FFmpeg Version Gates for Conditional Code
build.rsre-emits the sys crate's version metadata asffmpeg_x_yrustc cfgs, so version-specific behavior compiles only against the FFmpeg that provides it (e.g.#[cfg(ffmpeg_8_0)]). -
Global Side-Data Propagation (FFmpeg 8+)
Ported the FFmpeg 8fftoolsside-data plumbing: global side data (HDR mastering metadata, content light level, …) collected from input frames now flows throughbuffersrcparameters, is re-read from thebuffersinkafter graph configuration, and reaches the encoder'sdecoded_side_data. On FFmpeg 7.x the pre-existing per-frame path is kept bit-identical. -
Downmix Info Handling (FFmpeg 8+)
AV_FRAME_DATA_DOWNMIX_INFOis force-included in the input filter's side data (aresampleconsumes it at init time), and a downmix change between frames now triggers a filtergraph reinit, matchingfftools. -
CI Matrix Across Both FFmpeg Majors
Build & Clippy and the full test suite run per lane: FFmpeg 7.1 built from source and linked via pkg-config, and FFmpeg 8.1 statically linked throughffmpeg-sys-next/build.
Changed
-
Buffersrc Setup Order Follows FFmpeg 8 Requirements
Video buffer sources are now allocated, given their parameters (hw_frames_ctxincluded), and only then initialized — FFmpeg 8 validates hardware pixel formats already at init, andavfilter_graph_create_filterinitializes immediately. The new order behaves identically on FFmpeg 7.x. -
Pre-Mux Queue Flush Interleaved by DTS
When the muxer starts, the per-stream pre-muxing queues are merged by DTS instead of drained stream-by-stream, avoiding degraded interleaving (max_interleave_deltaoverflow) when several streams buffered heavily before the header was written. -
Filter Hardware Device Available at Build Time
The filter hw device is registered when the context is built and injected into the probe-only graph parse, so hardware filters that require a device at init no longer failFfmpegContext::builder().build(). -
RAII Owners for Raw FFI Pointers
FormatContext,FilterGraph,FilterInOut, andSubtitleowners now concentrate the raw FFmpeg pointer lifecycle, replacing hand-balanced free calls across the demux/mux/filter paths and closing leak paths on early error returns.
Fixed
-
FFmpeg 8: Audio Output Graphs Failed With
FilterGraph(ParseError(InvalidArgument))(#37)
ez-ffmpeg set theall_channel_countsoption onabuffersinkafter the filter was initialized. FFmpeg 8 rejects post-init sets of non-runtime options, so every audio output graph failed. The option was a no-op all along (it re-applied the audio default) and is removed; FFmpeg 9 removes the option entirely. -
FFmpeg 8: Hardware Pipelines Rejected at Buffer-Source Init
Hardware pixel formats with a not-yet-attachedhw_frames_ctxhit FFmpeg 8's new init-time validation. Fixed by the buffersrc setup-order change above. -
Out-of-Range Pixel Formats Rejected Before Filter Init
An out-of-contract pixel format from unsafe user code or a decoder defect could crash inside FFmpeg 8'sbuffersrcinit (unchecked descriptor dereference). The descriptor is validated before parameters are applied, restoring the old args-path boundary on both majors. -
Filtergraph Fallback Frame Was Never Filled
The probe codec context behind each input's fallback frame stayed at codec defaults (format=-1), so a stream that reached EOF before its first frame could never configure the graph. The fallback now carries the stream's real parameters. -
Decoder-Open and Subtitle Leaks
Plugged three decoder-open leak paths viaCodecContextRAII plus an opaque guard, and a decoded-subtitle leak via the newSubtitleowner. -
docs.rs Build
Kept a FFmpeg 7.0+ symbol out of docs.rs builds (its build image generates bindings against an older FFmpeg) and moved the docs stubs behind abuild.rscfg so--all-featuresbuilds always compile the real FFmpeg path. -
Test Isolation
Scheduler tests each write their own output file instead of sharingoutput.mp4(parallel runs truncated each other), andtest_stopwaits deterministically for the muxer's first bytes instead of sleeping.