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}