1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
//! # ff-encode
//!
//! Video and audio encoding - the Rust way.
// FFmpeg binding requires unsafe code for C API calls
// Raw pointer operations are necessary for FFmpeg C API
// Casting between C and Rust types
// C string literals
// Code structure warnings
//!
//! This crate provides video and audio encoding functionality for timeline export.
//! It supports automatic codec selection with LGPL compliance, hardware acceleration,
//! and provides a clean Builder pattern API.
//!
//! ## Features
//!
//! - **Video Encoding**: H.264, H.265, VP9, AV1, `ProRes`, `DNxHD`
//! - **Audio Encoding**: AAC, Opus, MP3, FLAC, PCM, Vorbis
//! - **Hardware Acceleration**: NVENC, QSV, AMF, `VideoToolbox`, VA-API
//! - **LGPL Compliance**: Automatic codec fallback when GPL features disabled
//! - **Progress Callbacks**: Real-time encoding progress updates
//! - **Builder Pattern**: Ergonomic encoder configuration
//!
//! ## Usage
//!
//! ### Basic Encoding
//!
//! ```ignore
//! use ff_encode::{VideoEncoder, VideoCodec, AudioCodec, BitrateMode, Preset};
//! use ff_format::VideoFrame;
//!
//! // Create encoder with Builder pattern
//! let mut encoder = VideoEncoder::create("output.mp4")?
//! .video(1920, 1080, 30.0) // resolution, FPS
//! .video_codec(VideoCodec::H264) // codec
//! .bitrate_mode(BitrateMode::Cbr(8_000_000)) // 8 Mbps
//! .preset(Preset::Medium) // speed/quality balance
//! .audio(48000, 2) // sample rate, channels
//! .audio_codec(AudioCodec::Aac)
//! .audio_bitrate(192_000) // 192 kbps
//! .build()?;
//!
//! // Check actual codec used
//! println!("Video codec: {}", encoder.actual_video_codec());
//! println!("Audio codec: {}", encoder.actual_audio_codec());
//!
//! // Push frames
//! for frame in frames {
//! encoder.push_video(&frame)?;
//! }
//!
//! // Push audio
//! encoder.push_audio(&audio_samples)?;
//!
//! // Finish encoding
//! encoder.finish()?;
//! ```
//!
//! ### Progress Callbacks
//!
//! ```ignore
//! use ff_encode::{VideoEncoder, EncodeProgress};
//!
//! // Simple closure-based callback
//! let mut encoder = VideoEncoder::create("output.mp4")?
//! .video(1920, 1080, 30.0)
//! .on_progress(|progress| {
//! println!("Encoded {} frames ({:.1}%) at {:.1} fps",
//! progress.frames_encoded,
//! progress.percent(),
//! progress.current_fps
//! );
//! })
//! .build()?;
//! ```
//!
//! ### Progress Callbacks with Cancellation
//!
//! ```ignore
//! use ff_encode::{VideoEncoder, EncodeProgressCallback, EncodeProgress};
//! use std::sync::Arc;
//! use std::sync::atomic::{AtomicBool, Ordering};
//!
//! struct CancellableProgress {
//! cancelled: Arc<AtomicBool>,
//! }
//!
//! impl EncodeProgressCallback for CancellableProgress {
//! fn on_progress(&mut self, progress: &EncodeProgress) {
//! println!("Progress: {:.1}%", progress.percent());
//! }
//!
//! fn should_cancel(&self) -> bool {
//! self.cancelled.load(Ordering::Relaxed)
//! }
//! }
//!
//! let cancelled = Arc::new(AtomicBool::new(false));
//! let mut encoder = VideoEncoder::create("output.mp4")?
//! .video(1920, 1080, 30.0)
//! .progress_callback(CancellableProgress {
//! cancelled: cancelled.clone()
//! })
//! .build()?;
//!
//! // Later, to cancel encoding:
//! cancelled.store(true, Ordering::Relaxed);
//! ```
//!
//! ### Hardware Encoding
//!
//! ```ignore
//! use ff_encode::{VideoEncoder, HardwareEncoder};
//!
//! // Check available hardware encoders
//! for hw in HardwareEncoder::available() {
//! println!("Available: {:?}", hw);
//! }
//!
//! // Create encoder with auto hardware detection
//! let mut encoder = VideoEncoder::create("output.mp4")?
//! .video(1920, 1080, 60.0)
//! .hardware_encoder(HardwareEncoder::Auto) // auto-detect
//! .build()?;
//!
//! // Check what encoder was actually used
//! println!("Using: {}", encoder.actual_video_codec());
//! println!("Hardware encoder: {:?}", encoder.hardware_encoder());
//! println!("Is hardware encoding: {}", encoder.is_hardware_encoding());
//! ```
//!
//! ## LGPL Compliance & Commercial Use
//!
//! **By default, this crate is LGPL-compliant and safe for commercial use without licensing fees.**
//!
//! ### Default Behavior (LGPL-Compatible)
//!
//! When H.264/H.265 encoding is requested, the encoder automatically selects codecs in this priority:
//!
//! 1. **Hardware encoders** (LGPL-compatible, no licensing fees):
//! - NVIDIA NVENC (h264_nvenc, hevc_nvenc)
//! - Intel Quick Sync Video (h264_qsv, hevc_qsv)
//! - AMD AMF/VCE (h264_amf, hevc_amf)
//! - Apple VideoToolbox (h264_videotoolbox, hevc_videotoolbox)
//! - VA-API (h264_vaapi, hevc_vaapi) - Linux
//!
//! 2. **Fallback to royalty-free codecs**:
//! - For H.264 request → VP9 (libvpx-vp9)
//! - For H.265 request → AV1 (libaom-av1)
//!
//! ### GPL Feature (Commercial Licensing Required)
//!
//! Enable GPL codecs (libx264, libx265) only if:
//! - You have appropriate licenses from MPEG LA, or
//! - Your software is GPL-licensed (open source), or
//! - For non-commercial/educational use only
//!
//! ```toml
//! # WARNING: Requires GPL compliance and licensing fees for commercial use
//! ff-encode = { version = "0.1", features = ["gpl"] }
//! ```
//!
//! ### Checking Compliance at Runtime
//!
//! You can verify which encoder was selected:
//!
//! ```ignore
//! let encoder = VideoEncoder::create("output.mp4")?
//! .video(1920, 1080, 30.0)
//! .video_codec(VideoCodec::H264)
//! .build()?;
//!
//! println!("Using: {}", encoder.actual_video_codec());
//! println!("LGPL compliant: {}", encoder.is_lgpl_compliant());
//! ```
pub use ;
pub use EncodeError;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use AsyncAudioEncoder;
pub use AsyncVideoEncoder;