ff_encode/codec.rs
1//! Codec definitions for encoding.
2
3/// Video codec for encoding.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
5#[non_exhaustive]
6pub enum VideoCodec {
7 /// H.264 / AVC (most compatible)
8 #[default]
9 H264,
10
11 /// H.265 / HEVC (high compression)
12 H265,
13
14 /// VP9 (`WebM`, royalty-free)
15 Vp9,
16
17 /// AV1 (latest, high compression, LGPL compatible)
18 Av1,
19
20 /// `ProRes` (Apple, editing)
21 ProRes,
22
23 /// `DNxHD`/`DNxHR` (Avid, editing)
24 DnxHd,
25
26 /// MPEG-4
27 Mpeg4,
28}
29
30impl VideoCodec {
31 /// Check if this codec specification is LGPL compatible.
32 ///
33 /// Returns `true` for codecs that can be used without GPL licensing.
34 ///
35 /// **Important**: This indicates the codec family's licensing, not the actual encoder used.
36 /// H.264 and H.265 return `false` because their software encoders (libx264/libx265) are GPL,
37 /// but hardware encoders (NVENC, QSV, etc.) are LGPL-compatible.
38 ///
39 /// Use [`VideoEncoder::is_lgpl_compliant()`](crate::VideoEncoder::is_lgpl_compliant) to check
40 /// the actual encoder selected at runtime.
41 ///
42 /// # LGPL-Compatible Codecs
43 ///
44 /// - `VP9` - Google's royalty-free codec (libvpx-vp9)
45 /// - `AV1` - Next-gen royalty-free codec (libaom-av1)
46 /// - `ProRes` - Apple's professional codec
47 /// - `DNxHD` - Avid's professional codec
48 /// - `MPEG4` - ISO MPEG-4 Part 2
49 ///
50 /// # GPL Codecs (require licensing for commercial use)
51 ///
52 /// - `H264` - Requires MPEG LA license (when using libx264)
53 /// - `H265` - Requires MPEG LA license (when using libx265)
54 ///
55 /// Note: Hardware H.264/H.265 encoders are LGPL-compatible and don't require licensing fees.
56 #[must_use]
57 pub const fn is_lgpl_compatible(self) -> bool {
58 match self {
59 Self::Vp9 | Self::Av1 | Self::Mpeg4 | Self::ProRes | Self::DnxHd => true,
60 Self::H264 | Self::H265 => false, // libx264/libx265 are GPL
61 }
62 }
63
64 /// Get default file extension for this codec.
65 #[must_use]
66 pub const fn default_extension(self) -> &'static str {
67 match self {
68 Self::Vp9 | Self::Av1 => "webm",
69 _ => "mp4",
70 }
71 }
72}
73
74/// Audio codec for encoding.
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
76#[non_exhaustive]
77pub enum AudioCodec {
78 /// AAC (most compatible)
79 #[default]
80 Aac,
81
82 /// Opus (high quality, low latency)
83 Opus,
84
85 /// MP3
86 Mp3,
87
88 /// FLAC (lossless)
89 Flac,
90
91 /// PCM (uncompressed)
92 Pcm,
93
94 /// Vorbis (OGG)
95 Vorbis,
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_video_codec_lgpl() {
104 assert!(VideoCodec::Vp9.is_lgpl_compatible());
105 assert!(VideoCodec::Av1.is_lgpl_compatible());
106 assert!(VideoCodec::Mpeg4.is_lgpl_compatible());
107 assert!(!VideoCodec::H264.is_lgpl_compatible());
108 assert!(!VideoCodec::H265.is_lgpl_compatible());
109 }
110
111 #[test]
112 fn test_video_codec_extension() {
113 assert_eq!(VideoCodec::H264.default_extension(), "mp4");
114 assert_eq!(VideoCodec::Vp9.default_extension(), "webm");
115 assert_eq!(VideoCodec::Av1.default_extension(), "webm");
116 }
117
118 #[test]
119 fn test_default_codecs() {
120 assert_eq!(VideoCodec::default(), VideoCodec::H264);
121 assert_eq!(AudioCodec::default(), AudioCodec::Aac);
122 }
123}