realsense_rust/frame/prelude.rs
1//! Traits for describing frame operations.
2//!
3//! Many rs2 frame types hold certain data structures in common, but have
4//! different functionalities. These are encapsulated by the `*FrameEx` traits,
5//! with the wildcard describing the specialization that goes with that type.
6
7use crate::{
8 kind::{Rs2Exception, Rs2Extension, Rs2FrameMetadata, Rs2StreamKind, Rs2TimestampDomain},
9 sensor::Sensor,
10 stream_profile::StreamProfile,
11};
12use anyhow::Result;
13use realsense_sys as sys;
14use std::ptr::NonNull;
15use thiserror::Error;
16
17/// How many bits are in a byte? Who can truly say.
18pub const BITS_PER_BYTE: i32 = 8;
19
20/// Occurs when a frame type cannot be constructed from the given data.
21#[derive(Error, Debug)]
22pub enum FrameConstructionError {
23 /// Could not get frame width.
24 #[error("Could not get frame width. Type: {0}; Reason: {1}")]
25 CouldNotGetWidth(Rs2Exception, String),
26 /// Could not get frame height.
27 #[error("Could not get frame height. Type: {0}; Reason: {1}")]
28 CouldNotGetHeight(Rs2Exception, String),
29 /// Could not get the pixel stride.
30 #[error("Could not get stride. Type: {0}; Reason: {1}")]
31 CouldNotGetStride(Rs2Exception, String),
32 /// Could not get the bit count per pixel.
33 #[error("Could not get bits-per-pixel. Type: {0}; Reason: {1}")]
34 CouldNotGetBitsPerPixel(Rs2Exception, String),
35 /// Could not get the frame timestamp.
36 #[error("Could not get timestamp. Type: {0}; Reason: {1}")]
37 CouldNotGetTimestamp(Rs2Exception, String),
38 /// Could not get the frame timestamp's time domain, e.g. to which
39 /// clock its time is relative.
40 #[error("Could not get timestamp domain. Type: {0}; Reason: {1}")]
41 CouldNotGetTimestampDomain(Rs2Exception, String),
42 /// Could not get the frame number.
43 #[error("Could not get frame number. Type: {0}; Reason: {1}")]
44 CouldNotGetFrameNumber(Rs2Exception, String),
45 /// Could not get the stream profile that describes the frame.
46 #[error("Could not get frame stream profile. Type: {0}; Reason: {1}")]
47 CouldNotGetFrameStreamProfile(Rs2Exception, String),
48 /// Could not get the total data size of the frame in bytes.
49 #[error("Could not get data size (in bytes). Type: {0}; Reason: {1}")]
50 CouldNotGetDataSize(Rs2Exception, String),
51 /// Could not get the data of the frame.
52 #[error("Could not get pointer to frame data. Type: {0}; Reason: {1}")]
53 CouldNotGetData(Rs2Exception, String),
54 /// Could not get the number of points in a Points frame.
55 #[error("Could not get number of points: Type: {0}; Reason: {1}")]
56 CouldNotGetPointCount(Rs2Exception, String),
57}
58
59/// Occurs when certain data cannot be derived from a Depth frame.
60#[derive(Error, Debug)]
61pub enum DepthError {
62 /// Cannot derive distance.
63 #[error("Could not get distance. Type: {0}; Reason: {1}")]
64 CouldNotGetDistance(Rs2Exception, String),
65 /// Cannot derive the depth units used.
66 #[error("Could not get depth units. Type: {0}; Reason: {1}")]
67 CouldNotGetDepthUnits(Rs2Exception, String),
68}
69
70/// Occurs when a baseline cannot be derived from a Disparity frame.
71#[derive(Error, Debug)]
72#[error("Could not get baseline. Type: {0}; Reason: {1}")]
73pub struct DisparityError(pub Rs2Exception, pub String);
74
75/// Cannot get the frame sensor.
76#[derive(Error, Debug)]
77#[error("Could not get frame sensor. Type: {0}; Reason: {1}")]
78pub struct CouldNotGetFrameSensorError(pub Rs2Exception, pub String);
79
80/// Describes common functionality across frame types.
81pub trait FrameEx {
82 /// Get the stream profile associated with the frame.
83 fn stream_profile(&self) -> &StreamProfile;
84
85 /// Get the sensor associated with the frame.
86 fn sensor(&self) -> Result<Sensor>;
87
88 /// Get the frame number.
89 fn frame_number(&self) -> u64;
90
91 /// Get the frame timestamp.
92 fn timestamp(&self) -> f64;
93
94 /// Get the RealSense timestamp domain for the current timestamp.
95 fn timestamp_domain(&self) -> Rs2TimestampDomain;
96
97 /// Get frame metadata.
98 ///
99 /// Returns `None` if the `metadata_kind` is not supported by the frame type.
100 fn metadata(&self, metadata_kind: Rs2FrameMetadata) -> Option<std::os::raw::c_longlong>;
101
102 /// Test whether the metadata arguemnt is supported by the frame.
103 fn supports_metadata(&self, metadata_kind: Rs2FrameMetadata) -> bool;
104
105 /// Get (and own) the underlying frame pointer for this frame.
106 ///
107 /// This is primarily useful for passing this frame forward to a processing block or blocks
108 /// (either via frame queue, directly, callback, etc).
109 ///
110 /// # Safety
111 ///
112 /// This does not destroy the underlying frame pointer once self
113 /// goes out of scope. Instead, the program expects that whatever
114 /// object was assigned to by this function now manages the lifetime.
115 unsafe fn get_owned_raw(self) -> NonNull<sys::rs2_frame>;
116}
117
118/// A trait for specifying which runtime stream kinds can be held within a frame type
119///
120/// This trait changes some of the semantics for how to think about librealsense2 frames. The
121/// reason for this is because frames in librealsense2 are more or less defined by three things:
122///
123/// 1. The data format ([`Rs2Format`](crate::kind::Rs2Format))
124/// 2. The extension type ([`Rs2Extension`](crate::kind::Rs2Extension)
125/// 3. The "stream kind" ([`Rs2StreamKind`](crate::kind::Rs2StreamKind))
126///
127/// Knowing these three things, you can uniquely describe any frame. We aim for our types to be
128/// categorically distinct. Unfortunately, all three of the data points above are not encoded in
129/// the type information for a frame in librealsense2, but are rather things we check at runtime.
130///
131pub trait FrameCategory {
132 /// Identifies the corresponding [`Rs2Extension`] for the type implementing this trait.
133 fn extension() -> Rs2Extension;
134
135 /// Identifies the stream kind corresponding to a given type implementing this trait.
136 fn kind() -> Rs2StreamKind;
137
138 /// Predicate for checking if the RS2 frame's stream has the same kind as the frame category.
139 fn has_correct_kind(&self) -> bool;
140}