Skip to content

ez-ffmpeg v0.12.0

Latest

Choose a tag to compare

@YeautyYE YeautyYE released this 06 Jul 15:25

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-next move 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-exported ffmpeg-next/ffmpeg-sys-next types (AVRational, AVMediaType, Frame) with their own 7.x pins must bump those pins to 8.1.

  • FFmpeg Version Gates for Conditional Code
    build.rs re-emits the sys crate's version metadata as ffmpeg_x_y rustc 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 8 fftools side-data plumbing: global side data (HDR mastering metadata, content light level, …) collected from input frames now flows through buffersrc parameters, is re-read from the buffersink after graph configuration, and reaches the encoder's decoded_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_INFO is force-included in the input filter's side data (aresample consumes it at init time), and a downmix change between frames now triggers a filtergraph reinit, matching fftools.

  • 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 through ffmpeg-sys-next/build.

Changed

  • Buffersrc Setup Order Follows FFmpeg 8 Requirements
    Video buffer sources are now allocated, given their parameters (hw_frames_ctx included), and only then initialized — FFmpeg 8 validates hardware pixel formats already at init, and avfilter_graph_create_filter initializes 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_delta overflow) 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 fail FfmpegContext::builder().build().

  • RAII Owners for Raw FFI Pointers
    FormatContext, FilterGraph, FilterInOut, and Subtitle owners 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 the all_channel_counts option on abuffersink after 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-attached hw_frames_ctx hit 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's buffersrc init (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 via CodecContext RAII plus an opaque guard, and a decoded-subtitle leak via the new Subtitle owner.

  • 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 a build.rs cfg so --all-features builds always compile the real FFmpeg path.

  • Test Isolation
    Scheduler tests each write their own output file instead of sharing output.mp4 (parallel runs truncated each other), and test_stop waits deterministically for the muxer's first bytes instead of sleeping.