ff_decode/shared/hardware.rs
1//! Hardware acceleration configuration for video decoding.
2
3/// Hardware acceleration configuration.
4///
5/// This enum specifies which hardware acceleration method to use for
6/// video decoding. Hardware acceleration can significantly improve
7/// decoding performance, especially for high-resolution content.
8///
9/// # Platform Support
10///
11/// | Mode | Platform | GPU Required |
12/// |------|----------|--------------|
13/// | [`Nvdec`](Self::Nvdec) | Windows/Linux | NVIDIA |
14/// | [`Qsv`](Self::Qsv) | Windows/Linux | Intel |
15/// | [`Amf`](Self::Amf) | Windows/Linux | AMD |
16/// | [`VideoToolbox`](Self::VideoToolbox) | macOS/iOS | Any |
17/// | [`Vaapi`](Self::Vaapi) | Linux | Various |
18///
19/// # Fallback Behavior
20///
21/// When [`Auto`](Self::Auto) is used, the decoder will try available
22/// accelerators in order of preference and fall back to software
23/// decoding if none are available.
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
25pub enum HardwareAccel {
26 /// Automatically detect and use available hardware.
27 ///
28 /// The decoder will probe for available hardware accelerators
29 /// and use the best one available. Falls back to software decoding
30 /// if no hardware acceleration is available.
31 #[default]
32 Auto,
33
34 /// Disable hardware acceleration (CPU only).
35 ///
36 /// Forces software decoding using the CPU. This may be useful for
37 /// debugging, consistency, or when hardware acceleration causes issues.
38 None,
39
40 /// NVIDIA NVDEC.
41 ///
42 /// Uses NVIDIA's dedicated video decoding hardware. Supports most
43 /// common codecs including H.264, H.265, VP9, and AV1 (on newer GPUs).
44 /// Requires an NVIDIA GPU with NVDEC support.
45 Nvdec,
46
47 /// Intel Quick Sync Video.
48 ///
49 /// Uses Intel's integrated GPU video engine. Available on most
50 /// Intel CPUs with integrated graphics. Supports H.264, H.265,
51 /// VP9, and AV1 (on newer platforms).
52 Qsv,
53
54 /// AMD Advanced Media Framework.
55 ///
56 /// Uses AMD's dedicated video decoding hardware. Available on AMD
57 /// GPUs and APUs. Supports H.264, H.265, and VP9.
58 Amf,
59
60 /// Apple `VideoToolbox`.
61 ///
62 /// Uses Apple's hardware video decoding on macOS and iOS. Works with
63 /// both Intel and Apple Silicon Macs. Supports H.264, H.265, and `ProRes`.
64 VideoToolbox,
65
66 /// Video Acceleration API (Linux).
67 ///
68 /// A Linux-specific API that provides hardware-accelerated video
69 /// decoding across different GPU vendors. Widely supported on
70 /// Intel, AMD, and NVIDIA GPUs on Linux.
71 Vaapi,
72}
73
74impl HardwareAccel {
75 /// Returns `true` if this represents an enabled hardware accelerator.
76 ///
77 /// Returns `false` for [`None`](Self::None) and [`Auto`](Self::Auto).
78 ///
79 /// # Examples
80 ///
81 /// ```
82 /// use ff_decode::HardwareAccel;
83 ///
84 /// assert!(!HardwareAccel::Auto.is_specific());
85 /// assert!(!HardwareAccel::None.is_specific());
86 /// assert!(HardwareAccel::Nvdec.is_specific());
87 /// assert!(HardwareAccel::Qsv.is_specific());
88 /// ```
89 #[must_use]
90 pub const fn is_specific(&self) -> bool {
91 !matches!(self, Self::Auto | Self::None)
92 }
93
94 /// Returns the name of the hardware accelerator.
95 ///
96 /// # Examples
97 ///
98 /// ```
99 /// use ff_decode::HardwareAccel;
100 ///
101 /// assert_eq!(HardwareAccel::Auto.name(), "auto");
102 /// assert_eq!(HardwareAccel::Nvdec.name(), "nvdec");
103 /// assert_eq!(HardwareAccel::VideoToolbox.name(), "videotoolbox");
104 /// ```
105 #[must_use]
106 pub const fn name(&self) -> &'static str {
107 match self {
108 Self::Auto => "auto",
109 Self::None => "none",
110 Self::Nvdec => "nvdec",
111 Self::Qsv => "qsv",
112 Self::Amf => "amf",
113 Self::VideoToolbox => "videotoolbox",
114 Self::Vaapi => "vaapi",
115 }
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
124 fn hardware_accel_default_should_be_auto() {
125 let accel = HardwareAccel::default();
126 assert_eq!(accel, HardwareAccel::Auto);
127 }
128
129 #[test]
130 fn hardware_accel_is_specific_should_return_false_for_auto_and_none() {
131 assert!(!HardwareAccel::Auto.is_specific());
132 assert!(!HardwareAccel::None.is_specific());
133 }
134
135 #[test]
136 fn hardware_accel_is_specific_should_return_true_for_explicit_accelerators() {
137 assert!(HardwareAccel::Nvdec.is_specific());
138 assert!(HardwareAccel::Qsv.is_specific());
139 assert!(HardwareAccel::Amf.is_specific());
140 assert!(HardwareAccel::VideoToolbox.is_specific());
141 assert!(HardwareAccel::Vaapi.is_specific());
142 }
143
144 #[test]
145 fn hardware_accel_name_should_return_correct_strings() {
146 assert_eq!(HardwareAccel::Auto.name(), "auto");
147 assert_eq!(HardwareAccel::None.name(), "none");
148 assert_eq!(HardwareAccel::Nvdec.name(), "nvdec");
149 assert_eq!(HardwareAccel::Qsv.name(), "qsv");
150 assert_eq!(HardwareAccel::Amf.name(), "amf");
151 assert_eq!(HardwareAccel::VideoToolbox.name(), "videotoolbox");
152 assert_eq!(HardwareAccel::Vaapi.name(), "vaapi");
153 }
154
155 #[test]
156 fn hardware_accel_variants_should_be_accessible() {
157 let accels = [
158 HardwareAccel::Auto,
159 HardwareAccel::None,
160 HardwareAccel::Nvdec,
161 HardwareAccel::Qsv,
162 HardwareAccel::Amf,
163 HardwareAccel::VideoToolbox,
164 HardwareAccel::Vaapi,
165 ];
166 for accel in accels {
167 let _ = format!("{accel:?}");
168 }
169 }
170}