Skip to main content

oximedia_transcode/hw_accel/
capabilities.rs

1//! Hardware acceleration capability types.
2//!
3//! Provides the rich capability model returned by platform probing:
4//! [`HwKind`], [`HwAccelDevice`], and [`HwAccelCapabilities`].
5
6use std::path::PathBuf;
7
8// ─── HwKind ──────────────────────────────────────────────────────────────────
9
10/// High-level hardware acceleration family.
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub enum HwKind {
13    /// Apple VideoToolbox (macOS / iOS).
14    VideoToolbox,
15    /// Video Acceleration API (Linux, via DRM/KMS — Intel, AMD, Nouveau).
16    Vaapi,
17    /// CUDA-based hardware acceleration (NVIDIA NVENC/NVDEC).
18    ///
19    /// Included for completeness; probing requires presence of
20    /// `/dev/nvidia0` on Linux. Windows probing is not yet implemented.
21    Cuda,
22}
23
24// ─── HwAccelDevice ───────────────────────────────────────────────────────────
25
26/// A single hardware-accelerated device discovered during platform probing.
27///
28/// Codec names follow the OxiMedia convention (`"h264"`, `"hevc"`, `"av1"`,
29/// `"vp9"`, `"vp8"`, `"mjpeg"`).  Note that OxiMedia's Green-List-only
30/// [`CodecId`](oximedia_core::types::CodecId) does not include H.264/HEVC;
31/// those names appear here because VideoToolbox and VAAPI do in fact support
32/// them on the underlying OS hardware — they are reported verbatim so callers
33/// can decide whether to use them via FFmpeg compat or platform APIs.
34#[derive(Debug, Clone)]
35pub struct HwAccelDevice {
36    /// Backend kind (VideoToolbox, VAAPI, …).
37    pub kind: HwKind,
38    /// Kernel-level driver name, if detectable (e.g., `"i915"`, `"amdgpu"`).
39    pub driver: Option<String>,
40    /// DRI render node path (Linux only, e.g., `/dev/dri/renderD128`).
41    pub render_node: Option<PathBuf>,
42    /// Codec names supported by this device.
43    pub supported_codecs: Vec<String>,
44    /// Maximum encode/decode width in pixels.
45    pub max_width: u32,
46    /// Maximum encode/decode height in pixels.
47    pub max_height: u32,
48    /// Whether HDR (10-bit, PQ/HLG) is supported.
49    pub supports_hdr: bool,
50}
51
52impl HwAccelDevice {
53    /// Returns `true` if this device advertises support for `codec`.
54    ///
55    /// Comparison is case-insensitive.
56    #[must_use]
57    pub fn supports_codec(&self, codec: &str) -> bool {
58        let lower = codec.to_lowercase();
59        self.supported_codecs
60            .iter()
61            .any(|c| c.to_lowercase() == lower)
62    }
63}
64
65// ─── HwAccelCapabilities ─────────────────────────────────────────────────────
66
67/// Set of hardware-accelerated devices found on the current system.
68///
69/// Obtained via [`detect_hw_accel_caps`](crate::hw_accel::detect_hw_accel_caps)
70/// (cached for the process lifetime) or
71/// [`detect_hw_accel_with_probe`](crate::hw_accel::detect_hw_accel_with_probe)
72/// (for tests / dependency injection).
73#[derive(Debug, Clone, Default)]
74pub struct HwAccelCapabilities {
75    /// Discovered devices, in probe order.
76    pub devices: Vec<HwAccelDevice>,
77}
78
79impl HwAccelCapabilities {
80    /// Empty capability set — used when no hardware is found or detection is
81    /// unsupported on this platform.
82    #[must_use]
83    pub fn none() -> Self {
84        Self::default()
85    }
86
87    /// Returns `true` if no hardware devices were found.
88    #[must_use]
89    pub fn is_empty(&self) -> bool {
90        self.devices.is_empty()
91    }
92
93    /// Returns the first device that supports `codec`, if any.
94    #[must_use]
95    pub fn device_for_codec(&self, codec: &str) -> Option<&HwAccelDevice> {
96        self.devices.iter().find(|d| d.supports_codec(codec))
97    }
98}