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}