ez_ffmpeg/lib.rs
1// In test builds, libtest-generated code references test items through the
2// deprecated `opengl` module path, which a file-level allow cannot cover.
3#![cfg_attr(test, allow(deprecated))]
4
5//! # ez-ffmpeg
6//!
7//! **ez-ffmpeg** provides a safe and ergonomic Rust interface for [FFmpeg](https://ffmpeg.org)
8//! integration. By abstracting away much of the raw C API complexity,
9//! It abstracts the complexity of the raw C API, allowing you to configure media pipelines,
10//! perform transcoding and filtering, and inspect streams with ease.
11//!
12//! ## Crate Layout
13//!
14//! - **`core`**: The foundational module that contains the main building blocks for configuring
15//! and running FFmpeg pipelines. This includes:
16//! - `Input` / `Output`: Descriptors for where media data comes from and goes to (files, URLs,
17//! custom I/O callbacks, etc.).
18//! - `FilterComplex` and [`FrameFilter`](filter::frame_filter::FrameFilter): Mechanisms for applying FFmpeg filter graphs or
19//! custom transformations.
20//! - `container_info`: Utilities to extract information about the container, such as duration and format details.
21//! - `stream_info`: Utilities to query media metadata (duration, codecs, etc.).
22//! - `hwaccel`: Helpers for enumerating and configuring hardware-accelerated video codecs
23//! (CUDA, VAAPI, VideoToolbox, etc.).
24//! - `codec`: Tools to list and inspect available encoders/decoders.
25//! - `device`: Utilities to discover system cameras, microphones, and other input devices.
26//! - `filter`: Query FFmpeg's built-in filters and infrastructure for building custom frame-processing filters.
27//! - `context`: Houses [`FfmpegContext`] for assembling an FFmpeg job.
28//! - `scheduler`: Provides [`FfmpegScheduler`] which manages the lifecycle of that job.
29//!
30//! - **`wgpu_filter`** (feature `"wgpu"`): GPU-accelerated frame filters via wgpu
31//! (Vulkan/Metal/DX12/GL). Provide a WGSL fragment shader and apply effects with
32//! correct color handling, headless operation, and GPU/CPU overlap.
33//!
34//! - **`opengl`** (feature `"opengl"`, deprecated): The former OpenGL filter path,
35//! superseded by `wgpu_filter`. Kept for backward compatibility; it requires a
36//! display connection and will be removed in a future major release.
37//!
38//! - **`rtmp`** (feature `"rtmp"`): Embedded RTMP server `EmbedRtmpServer` built for production streaming,
39//! using native epoll/kqueue/WSAPoll via libc FFI (edge-triggered on Linux/macOS, level-triggered on Windows),
40//! zero-copy GOP fanout with `Arc<[FrameData]>`, and tiered backpressure (1/2/4MB) on a 2-thread model;
41//! 10,000+ conns on Linux/macOS (8,000 on Windows) with in-process ingest (no TCP between FFmpeg and server).
42//!
43//! - **`flv`** (feature `"flv"`): Provides data structures and helpers for handling FLV
44//! containers, useful if you’re working with RTMP or other FLV-based workflows.
45//!
46//! - **`subtitle`** (feature `"subtitle"`): Burns ASS/SRT subtitles onto video frames inside
47//! the frame pipeline with a pure-Rust renderer — independent of whether the linked FFmpeg
48//! was built with `--enable-libass`. Accepts subtitle files or in-memory scripts and
49//! explicit font files.
50//!
51//! ## Basic Usage
52//!
53//! For a simple pipeline, you typically do the following:
54//!
55//! 1. Build a [`FfmpegContext`] by specifying at least one [input](Input)
56//! and one [output](Output). Optionally, add filter descriptions
57//! (`filter_desc`) or attach [`FrameFilter`](filter::frame_filter::FrameFilter) pipelines at either the input (post-decode)
58//! or the output (pre-encode) stage.
59//! 2. Create an [`FfmpegScheduler`] from that context, then call `start()` and `wait()` (or `.await`
60//! if you enable the `"async"` feature) to run the job.
61//!
62//! ```rust,ignore
63//! use ez_ffmpeg::FfmpegContext;
64//! use ez_ffmpeg::FfmpegScheduler;
65//!
66//! fn main() -> Result<(), Box<dyn std::error::Error>> {
67//! // 1. Build the FFmpeg context
68//! let context = FfmpegContext::builder()
69//! .input("input.mp4")
70//! .filter_desc("hue=s=0") // Example filter: desaturate
71//! .output("output.mov")
72//! .build()?;
73//!
74//! // 2. Run it via FfmpegScheduler (sync mode)
75//! let result = FfmpegScheduler::new(context)
76//! .start()?
77//! .wait();
78//! result?; // If any error occurred, propagate it
79//! Ok(())
80//! }
81//! ```
82//!
83//! ## Feature Flags
84//!
85//! **`ez-ffmpeg`** uses Cargo features to provide optional functionality. By default, no optional
86//! features are enabled, allowing you to keep dependencies minimal. You can enable features as needed
87//! in your `Cargo.toml`:
88//!
89//! ```toml
90//! [dependencies.ez-ffmpeg]
91//! version = "*"
92//! features = ["wgpu", "rtmp", "flv", "async"]
93//! ```
94//!
95//! ### Core Features
96//!
97//! - **`wgpu`**: Enables wgpu-based GPU filters (WGSL shaders, headless-capable).
98//! - **`opengl`** (deprecated): Enables the former OpenGL-based filters; superseded by `wgpu`.
99//! - **`rtmp`**: Embedded RTMP server tuned for scale (10,000+ conns on Linux/macOS, 8,000 on Windows),
100//! native epoll/kqueue/WSAPoll IO (edge-triggered on Linux/macOS), zero-copy GOP, and in-process ingest
101//! that avoids TCP between FFmpeg and server.
102//! - **`flv`**: Adds FLV container parsing and handling.
103//! - **`subtitle`**: Native ASS/SRT subtitle burn-in rendered in pure Rust — no system
104//! libraries beyond FFmpeg itself (see the `subtitle` module docs).
105//! - **`async`**: Makes the [`FfmpegScheduler`] wait method asynchronous (you can `.await` it).
106//! - **`static`**: Uses static linking for FFmpeg libraries (via `ffmpeg-next/static`).
107//!
108//! ## Relationship to the FFmpeg CLI
109//!
110//! The transcoding pipeline (demux -> decode -> filter -> encode -> mux) is
111//! ported from the FFmpeg CLI sources, `fftools/ffmpeg` of **FFmpeg 7.x**:
112//! function names, timestamp handling and scheduling semantics follow that
113//! release, and code comments cite the corresponding fftools file and line
114//! (line numbers refer to the FFmpeg `n7.1` tag).
115//! If you know `ffmpeg_demux.c` or `ffmpeg_filter.c`, grepping this crate
116//! for the same function names (`ts_fixup`, `video_sync_process`,
117//! `enc_open`, `mux_fixup_ts`, ...) lands in the equivalent Rust.
118//!
119//! Not every CLI feature is implemented. Notable gaps: progress/stats
120//! reporting (`-progress`), sub2video (rendering bitmap subtitles into
121//! video), `-shortest` cross-stream sync, bitstream filters (`-bsf`),
122//! keyframe forcing (`-force_key_frames`), `-fix_sub_duration`, two-pass
123//! encoding, and attachments. Unsupported paths fail with explicit errors
124//! rather than approximations.
125//!
126//! ## Logging
127//!
128//! FFmpeg's own diagnostics (av_log) are redirected into the Rust `log`
129//! facade under the [`FFMPEG_LOG_TARGET`] target. Without a logger installed
130//! (env_logger, tracing-log, ...) all FFmpeg messages are silently dropped —
131//! including decoder errors that explain a failing job. Use
132//! [`set_ffmpeg_log_level`] to bound the forwarded verbosity and
133//! `Input::set_log_level_offset` to shift it per input.
134//!
135//! ## License Notice
136//!
137//! ez-ffmpeg is licensed under your choice of MIT, Apache-2.0, or MPL-2.0
138//! (matching the `license` field in Cargo.toml).
139//!
140//! **Note:** FFmpeg itself is subject to its own licensing terms. When enabling features that incorporate FFmpeg components,
141//! please ensure that your usage complies with FFmpeg's license.
142
143pub mod core;
144pub mod util;
145pub mod error;
146
147pub use self::core::context::ffmpeg_context::FfmpegContext;
148pub use self::core::context::input::Input;
149pub use self::core::context::output::Output;
150pub use self::core::scheduler::ffmpeg_scheduler::FfmpegScheduler;
151pub use self::core::container_info;
152pub use self::core::stream_info;
153pub use self::core::{set_ffmpeg_log_level, FfmpegLogLevel, FFMPEG_LOG_TARGET};
154pub use self::core::packet_scanner;
155pub use self::core::device;
156pub use self::core::hwaccel;
157pub use self::core::codec;
158pub use self::core::filter;
159pub use self::core::analysis;
160pub use self::core::recipes;
161
162pub use ffmpeg_sys_next::AVRational;
163pub use ffmpeg_sys_next::AVMediaType;
164pub use ffmpeg_next::Frame;
165
166
167#[cfg(feature = "opengl")]
168#[deprecated(
169 since = "0.11.0",
170 note = "the OpenGL filter path is superseded by `wgpu_filter` (feature \"wgpu\"): it needs a \
171 display connection and converts colors on the CPU; see the module docs for migration"
172)]
173pub mod opengl;
174#[cfg(feature = "opengl")]
175use surfman::declare_surfman;
176#[cfg(feature = "opengl")]
177declare_surfman!();
178
179#[cfg(feature = "wgpu")]
180pub mod wgpu_filter;
181
182#[cfg(feature = "rtmp")]
183pub mod rtmp;
184
185#[cfg(feature = "flv")]
186pub mod flv;
187
188#[cfg(feature = "subtitle")]
189pub mod subtitle;