playa_ffmpeg/
lib.rs

1//! # playa-ffmpeg
2//!
3//! Safe Rust bindings for FFmpeg 8.0 with vcpkg integration for simplified cross-platform builds.
4//!
5//! This crate provides idiomatic Rust wrappers around FFmpeg's C libraries, enabling multimedia
6//! processing including video/audio encoding, decoding, muxing, demuxing, filtering, and transcoding.
7//!
8//! ## Main Modules
9//!
10//! - [`codec`] - Audio/video/subtitle codecs (encoders and decoders)
11//! - [`mod@format`] - Container formats, streams, input/output contexts
12//! - [`util`] - Core utilities (frames, errors, color, channel layouts, dictionaries)
13//! - [`filter`] - Audio/video filtering and transformation graphs
14//! - [`software`] - Software scaling and resampling
15//! - [`device`] - Hardware input/output devices
16//!
17//! ## Quick Start
18//!
19//! ```ignore
20//! use playa_ffmpeg as ffmpeg;
21//!
22//! // Initialize FFmpeg (required before use)
23//! ffmpeg::init()?;
24//!
25//! // Open input file
26//! let input = ffmpeg::format::input(&"video.mp4")?;
27//!
28//! // Process streams...
29//! ```
30//!
31//! ## Feature Flags
32//!
33//! - `codec` (default) - Enable codec support
34//! - `format` (default) - Enable format/container support
35//! - `filter` (default) - Enable filtering support
36//! - `device` (default) - Enable device support
37//! - `software-scaling` (default) - Enable software video scaling
38//! - `software-resampling` (default) - Enable software audio resampling
39//! - `static` - Link FFmpeg statically
40//! - `build` - Build FFmpeg from source during compilation
41//!
42//! See `Cargo.toml` for additional codec-specific and licensing feature flags.
43
44#![allow(non_camel_case_types)]
45#![allow(clippy::missing_safety_doc)]
46#![allow(clippy::module_inception)]
47#![allow(clippy::too_many_arguments)]
48
49#[macro_use]
50extern crate bitflags;
51pub extern crate ffmpeg_sys_next as sys;
52#[cfg(feature = "image")]
53extern crate image;
54extern crate libc;
55
56/// Re-export of the raw FFI bindings from `ffmpeg-sys-next`.
57///
58/// Use this for direct access to FFmpeg's C API when the safe wrappers don't provide
59/// the needed functionality. Most users should prefer the safe wrappers in this crate.
60pub use sys as ffi;
61
62#[macro_use]
63pub mod util;
64pub use crate::util::{
65    channel_layout::{self, ChannelLayout},
66    chroma, color, dictionary,
67    dictionary::{Mut as DictionaryMut, Owned as Dictionary, Ref as DictionaryRef},
68    error::{self, Error},
69    frame::{self, Frame},
70    log,
71    mathematics::{self, Rescale, Rounding, rescale},
72    media, option, picture,
73    rational::{self, Rational},
74    time,
75};
76
77#[cfg(feature = "format")]
78pub mod format;
79#[cfg(feature = "format")]
80pub use crate::format::chapter::{Chapter, ChapterMut};
81#[cfg(feature = "format")]
82pub use crate::format::format::Format;
83#[cfg(feature = "format")]
84pub use crate::format::stream::{Stream, StreamMut};
85
86#[cfg(feature = "codec")]
87pub mod codec;
88#[cfg(feature = "codec")]
89pub use crate::codec::audio_service::AudioService;
90#[cfg(feature = "codec")]
91pub use crate::codec::codec::Codec;
92#[cfg(feature = "codec")]
93pub use crate::codec::discard::Discard;
94#[cfg(feature = "codec")]
95pub use crate::codec::field_order::FieldOrder;
96#[cfg(feature = "codec")]
97pub use crate::codec::packet::{self, Packet};
98#[cfg(all(feature = "codec", not(feature = "ffmpeg_5_0")))]
99pub use crate::codec::picture::Picture;
100#[cfg(feature = "codec")]
101pub use crate::codec::subtitle::{self, Subtitle};
102#[cfg(feature = "codec")]
103pub use crate::codec::threading;
104#[cfg(feature = "codec")]
105pub use crate::codec::{decoder, encoder};
106
107#[cfg(feature = "device")]
108pub mod device;
109
110#[cfg(feature = "filter")]
111pub mod filter;
112#[cfg(feature = "filter")]
113pub use filter::Filter;
114
115pub mod software;
116
117/// Initializes the error handling subsystem.
118///
119/// Registers all FFmpeg error codes for proper error translation to Rust Error types.
120/// Called automatically by [`init()`].
121fn init_error() {
122    util::error::register_all();
123}
124
125/// Initializes the format/container subsystem (FFmpeg < 5.0).
126///
127/// Registers all available muxers and demuxers. In FFmpeg 5.0+, this is handled
128/// automatically and this function is a no-op.
129#[cfg(all(feature = "format", not(feature = "ffmpeg_5_0")))]
130fn init_format() {
131    format::register_all();
132}
133
134#[cfg(not(feature = "format"))]
135fn init_format() {}
136
137/// Initializes the device input/output subsystem.
138///
139/// Registers all available input and output devices (cameras, screen capture, etc.).
140/// Only active when the `device` feature is enabled.
141#[cfg(feature = "device")]
142fn init_device() {
143    device::register_all();
144}
145
146#[cfg(not(feature = "device"))]
147fn init_device() {}
148
149/// Initializes the filter subsystem (FFmpeg < 5.0).
150///
151/// Registers all available audio/video filters. In FFmpeg 5.0+, this is handled
152/// automatically and this function is a no-op.
153#[cfg(all(feature = "filter", not(feature = "ffmpeg_5_0")))]
154fn init_filter() {
155    filter::register_all();
156}
157
158#[cfg(not(feature = "filter"))]
159fn init_filter() {}
160
161/// Initializes the FFmpeg library.
162///
163/// This function must be called before using any other FFmpeg functionality. It initializes
164/// all subsystems including error handling, formats, devices, and filters.
165///
166/// # Note
167///
168/// - In FFmpeg 5.0+, most subsystems auto-register, but this call is still required for
169///   error handling and device initialization.
170/// - This function is thread-safe and can be called multiple times (subsequent calls are no-ops).
171/// - The `ffmpeg4`/`ffmpeg41`/`ffmpeg42`/`ffmpeg43` feature flags are deprecated as version
172///   detection is now automatic.
173///
174/// # Errors
175///
176/// Currently always returns `Ok(())`, but the return type is kept for future compatibility.
177///
178/// # Example
179///
180/// ```ignore
181/// use playa_ffmpeg as ffmpeg;
182///
183/// fn main() -> Result<(), ffmpeg::Error> {
184///     ffmpeg::init()?;
185///
186///     // Now safe to use FFmpeg functionality
187///     let input = ffmpeg::format::input(&"video.mp4")?;
188///     Ok(())
189/// }
190/// ```
191#[cfg_attr(
192    any(feature = "ffmpeg4", feature = "ffmpeg41", feature = "ffmpeg42"),
193    deprecated(note = "features ffmpeg4/ffmpeg41/ffmpeg42/ffmpeg43 are now auto-detected \
194        and will be removed in a future version")
195)]
196pub fn init() -> Result<(), Error> {
197    init_error();
198    #[cfg(not(feature = "ffmpeg_5_0"))]
199    init_format();
200    init_device();
201    #[cfg(not(feature = "ffmpeg_5_0"))]
202    init_filter();
203
204    Ok(())
205}