Skip to main content

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}