realsense_rust/pipeline/
inactive.rs1use super::{active::ActivePipeline, profile::PipelineProfile};
4use crate::{check_rs2_error, config::Config, context::Context, kind::Rs2Exception};
5use anyhow::Result;
6use realsense_sys as sys;
7use std::{convert::TryFrom, ptr::NonNull};
8use thiserror::Error;
9
10#[derive(Error, Debug)]
12pub enum PipelineConstructionError {
13 #[error("Could not create the pipeline from the provided context. Type: {0}; Reason {1}")]
15 CouldNotCreatePipelineFromContext(Rs2Exception, String),
16}
17
18#[derive(Error, Debug)]
20pub enum PipelineActivationError {
21 #[error("Could not successfully start the pipeline. Type: {0}; Reason: {1}")]
23 CouldNotStartPipelineError(Rs2Exception, String),
24 #[error("Config cannot be resolved by any active devices / stream combinations.")]
28 ConfigCannotBeResolved,
29}
30
31#[derive(Debug)]
33pub struct InactivePipeline {
34 pipeline_ptr: NonNull<sys::rs2_pipeline>,
36}
37
38impl Drop for InactivePipeline {
39 fn drop(&mut self) {
40 unsafe {
41 sys::rs2_delete_pipeline(self.pipeline_ptr.as_ptr());
42 }
43 }
44}
45
46unsafe impl Send for InactivePipeline {}
47
48impl TryFrom<&Context> for InactivePipeline {
49 type Error = anyhow::Error;
50
51 fn try_from(context: &Context) -> Result<Self, Self::Error> {
52 unsafe {
53 let mut err = std::ptr::null_mut::<sys::rs2_error>();
54 let context_ptr = context.get_raw();
55
56 let pipeline_ptr = sys::rs2_create_pipeline(context_ptr.as_ptr(), &mut err);
57 check_rs2_error!(
58 err,
59 PipelineConstructionError::CouldNotCreatePipelineFromContext
60 )?;
61
62 Ok(Self::new(NonNull::new(pipeline_ptr).unwrap()))
63 }
64 }
65}
66
67impl InactivePipeline {
68 pub(crate) fn new(pipeline_ptr: NonNull<sys::rs2_pipeline>) -> Self {
72 Self { pipeline_ptr }
73 }
74
75 pub fn start(self, config: Option<Config>) -> Result<ActivePipeline> {
79 unsafe {
80 let mut err = std::ptr::null_mut::<sys::rs2_error>();
81 let profile_ptr = if let Some(conf) = config {
82 if !self.can_resolve(&conf) {
83 return Err(anyhow::anyhow!(
84 PipelineActivationError::ConfigCannotBeResolved
85 ));
86 }
87
88 sys::rs2_pipeline_start_with_config(
89 self.pipeline_ptr.as_ptr(),
90 conf.get_raw().as_ptr(),
91 &mut err,
92 )
93 } else {
94 sys::rs2_pipeline_start(self.pipeline_ptr.as_ptr(), &mut err)
95 };
96 check_rs2_error!(err, PipelineActivationError::CouldNotStartPipelineError)?;
97
98 let profile = PipelineProfile::try_from(NonNull::new(profile_ptr).unwrap())?;
99 let active = ActivePipeline::new(self.pipeline_ptr, profile);
100
101 std::mem::forget(self);
102 Ok(active)
103 }
104 }
105
106 pub fn resolve(&self, config: &Config) -> Option<PipelineProfile> {
113 if !self.can_resolve(config) {
114 return None;
115 }
116
117 unsafe {
118 let mut err = std::ptr::null_mut::<sys::rs2_error>();
119 let profile_ptr = sys::rs2_config_resolve(
120 config.get_raw().as_ptr(),
121 self.pipeline_ptr.as_ptr(),
122 &mut err,
123 );
124
125 if err.as_ref().is_none() {
126 PipelineProfile::try_from(NonNull::new(profile_ptr).unwrap()).ok()
127 } else {
128 sys::rs2_free_error(err);
129 None
130 }
131 }
132 }
133
134 pub fn can_resolve(&self, config: &Config) -> bool {
143 unsafe {
144 let mut err = std::ptr::null_mut::<sys::rs2_error>();
145 let can_resolve = sys::rs2_config_can_resolve(
146 config.get_raw().as_ptr(),
147 self.pipeline_ptr.as_ptr(),
148 &mut err,
149 );
150
151 if err.as_ref().is_none() {
152 can_resolve != 0
153 } else {
154 sys::rs2_free_error(err);
155 false
156 }
157 }
158 }
159}